xref: /freebsd/sys/dev/syscons/daemon/daemon_saver.c (revision 02f2e93b60c2b91feac8f45c4c889a5a8e40d8a2)
1e8adebf2SKazutaka YOKOTA /*-
2e8adebf2SKazutaka YOKOTA  * Copyright (c) 1997 Sandro Sigala, Brescia, Italy.
3068eabc6SKazutaka YOKOTA  * Copyright (c) 1997 Chris Shenton
4e8adebf2SKazutaka YOKOTA  * Copyright (c) 1995 S ren Schmidt
5e8adebf2SKazutaka YOKOTA  * All rights reserved.
6e8adebf2SKazutaka YOKOTA  *
7e8adebf2SKazutaka YOKOTA  * Redistribution and use in source and binary forms, with or without
8e8adebf2SKazutaka YOKOTA  * modification, are permitted provided that the following conditions
9e8adebf2SKazutaka YOKOTA  * are met:
10e8adebf2SKazutaka YOKOTA  * 1. Redistributions of source code must retain the above copyright
11e8adebf2SKazutaka YOKOTA  *    notice, this list of conditions and the following disclaimer
12e8adebf2SKazutaka YOKOTA  *    in this position and unchanged.
13e8adebf2SKazutaka YOKOTA  * 2. Redistributions in binary form must reproduce the above copyright
14e8adebf2SKazutaka YOKOTA  *    notice, this list of conditions and the following disclaimer in the
15e8adebf2SKazutaka YOKOTA  *    documentation and/or other materials provided with the distribution.
16e8adebf2SKazutaka YOKOTA  *
17e8adebf2SKazutaka YOKOTA  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18e8adebf2SKazutaka YOKOTA  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19e8adebf2SKazutaka YOKOTA  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20e8adebf2SKazutaka YOKOTA  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21e8adebf2SKazutaka YOKOTA  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22e8adebf2SKazutaka YOKOTA  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23e8adebf2SKazutaka YOKOTA  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24e8adebf2SKazutaka YOKOTA  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25e8adebf2SKazutaka YOKOTA  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26e8adebf2SKazutaka YOKOTA  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27e8adebf2SKazutaka YOKOTA  *
2802f2e93bSKazutaka YOKOTA  *	$Id: daemon_saver.c,v 1.6 1997/07/15 14:49:16 yokota Exp $
29e8adebf2SKazutaka YOKOTA  */
30e8adebf2SKazutaka YOKOTA 
31e8adebf2SKazutaka YOKOTA #include <sys/param.h>
32e8adebf2SKazutaka YOKOTA #include <sys/systm.h>
33e8adebf2SKazutaka YOKOTA #include <sys/exec.h>
34e8adebf2SKazutaka YOKOTA #include <sys/sysent.h>
35e8adebf2SKazutaka YOKOTA #include <sys/lkm.h>
36ce834215SKazutaka YOKOTA #include <sys/malloc.h>
37f4863d1aSKazutaka YOKOTA #include <sys/kernel.h>
38f4863d1aSKazutaka YOKOTA #include <sys/sysctl.h>
39e8adebf2SKazutaka YOKOTA 
40e8adebf2SKazutaka YOKOTA #include <machine/md_var.h>
41ce834215SKazutaka YOKOTA #include <i386/include/pc/display.h>
42e8adebf2SKazutaka YOKOTA 
43ce834215SKazutaka YOKOTA #include <saver.h>
44e8adebf2SKazutaka YOKOTA 
45068eabc6SKazutaka YOKOTA #define CONSOLE_VECT(x, y) \
4602f2e93bSKazutaka YOKOTA 	((u_short*)(Crtat + (y)*cur_console->xsize + (x)))
47068eabc6SKazutaka YOKOTA 
48e8adebf2SKazutaka YOKOTA #define DAEMON_MAX_WIDTH	32
49e8adebf2SKazutaka YOKOTA #define DAEMON_MAX_HEIGHT	19
50e8adebf2SKazutaka YOKOTA 
51ce834215SKazutaka YOKOTA MOD_MISC(daemon_saver);
52ce834215SKazutaka YOKOTA 
53ce834215SKazutaka YOKOTA static char *message;
54ce834215SKazutaka YOKOTA static int messagelen;
55068eabc6SKazutaka YOKOTA 
56068eabc6SKazutaka YOKOTA /* Who is the author of this ASCII pic? */
57e8adebf2SKazutaka YOKOTA 
58e8adebf2SKazutaka YOKOTA static char *daemon_pic[] = {
59e8adebf2SKazutaka YOKOTA         "             ,        ,",
60e8adebf2SKazutaka YOKOTA 	"            /(        )`",
61e8adebf2SKazutaka YOKOTA 	"            \\ \\___   / |",
62e8adebf2SKazutaka YOKOTA 	"            /- _  `-/  '",
63e8adebf2SKazutaka YOKOTA 	"           (/\\/ \\ \\   /\\",
64e8adebf2SKazutaka YOKOTA 	"           / /   | `    \\",
65e8adebf2SKazutaka YOKOTA 	"           O O   ) /    |",
66e8adebf2SKazutaka YOKOTA 	"           `-^--'`<     '",
67e8adebf2SKazutaka YOKOTA 	"          (_.)  _  )   /",
68e8adebf2SKazutaka YOKOTA 	"           `.___/`    /",
69e8adebf2SKazutaka YOKOTA 	"             `-----' /",
70e8adebf2SKazutaka YOKOTA 	"<----.     __ / __   \\",
71e8adebf2SKazutaka YOKOTA 	"<----|====O)))==) \\) /====",
72e8adebf2SKazutaka YOKOTA 	"<----'    `--' `.__,' \\",
73e8adebf2SKazutaka YOKOTA 	"             |        |",
74e8adebf2SKazutaka YOKOTA 	"              \\       /       /\\",
75e8adebf2SKazutaka YOKOTA 	"         ______( (_  / \\______/",
76e8adebf2SKazutaka YOKOTA 	"       ,'  ,-----'   |",
77e8adebf2SKazutaka YOKOTA 	"       `--{__________)",
78e8adebf2SKazutaka YOKOTA 	NULL
79e8adebf2SKazutaka YOKOTA };
80e8adebf2SKazutaka YOKOTA 
81e8adebf2SKazutaka YOKOTA static char *daemon_attr[] = {
82e8adebf2SKazutaka YOKOTA         "             R        R",
83e8adebf2SKazutaka YOKOTA 	"            RR        RR",
84e8adebf2SKazutaka YOKOTA 	"            R RRRR   R R",
85e8adebf2SKazutaka YOKOTA 	"            RR W  RRR  R",
86e8adebf2SKazutaka YOKOTA 	"           RWWW W R   RR",
87e8adebf2SKazutaka YOKOTA 	"           W W   W R    R",
88e8adebf2SKazutaka YOKOTA 	"           B B   W R    R",
89e8adebf2SKazutaka YOKOTA 	"           WWWWWWRR     R",
90e8adebf2SKazutaka YOKOTA 	"          RRRR  R  R   R",
91e8adebf2SKazutaka YOKOTA 	"           RRRRRRR    R",
92e8adebf2SKazutaka YOKOTA 	"             RRRRRRR R",
93e8adebf2SKazutaka YOKOTA 	"YYYYYY     RR R RR   R",
94e8adebf2SKazutaka YOKOTA 	"YYYYYYYYYYRRRRYYR RR RYYYY",
95e8adebf2SKazutaka YOKOTA 	"YYYYYY    RRRR RRRRRR R",
96e8adebf2SKazutaka YOKOTA 	"             R        R",
97e8adebf2SKazutaka YOKOTA 	"              R       R       RR",
98e8adebf2SKazutaka YOKOTA 	"         CCCCCCR RR  R RRRRRRRR",
99e8adebf2SKazutaka YOKOTA 	"       CC  CCCCCCC   C",
100e8adebf2SKazutaka YOKOTA 	"       CCCCCCCCCCCCCCC",
101e8adebf2SKazutaka YOKOTA 	NULL
102e8adebf2SKazutaka YOKOTA };
103e8adebf2SKazutaka YOKOTA 
104068eabc6SKazutaka YOKOTA /*
105068eabc6SKazutaka YOKOTA  * Reverse a graphics character, or return unaltered if no mirror;
106068eabc6SKazutaka YOKOTA  * should do alphanumerics too, but I'm too lazy. <cshenton@it.hq.nasa.gov>
107068eabc6SKazutaka YOKOTA  */
108068eabc6SKazutaka YOKOTA 
109068eabc6SKazutaka YOKOTA static char
110068eabc6SKazutaka YOKOTA xflip_symbol(char symbol)
111068eabc6SKazutaka YOKOTA {
112068eabc6SKazutaka YOKOTA 	static const char lchars[] = "`'(){}[]\\/<>";
113068eabc6SKazutaka YOKOTA 	static const char rchars[] = "'`)(}{][/\\><";
114068eabc6SKazutaka YOKOTA 	int pos;
115068eabc6SKazutaka YOKOTA 
116068eabc6SKazutaka YOKOTA 	for (pos = 0; lchars[pos] != '\0'; pos++)
117068eabc6SKazutaka YOKOTA 		if (lchars[pos] == symbol)
118068eabc6SKazutaka YOKOTA 			return rchars[pos];
119068eabc6SKazutaka YOKOTA 
120068eabc6SKazutaka YOKOTA 	return symbol;
121068eabc6SKazutaka YOKOTA }
122e8adebf2SKazutaka YOKOTA 
123e8adebf2SKazutaka YOKOTA static void
12402f2e93bSKazutaka YOKOTA clear_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
12502f2e93bSKazutaka YOKOTA 	    int xlen, int ylen)
12602f2e93bSKazutaka YOKOTA {
12702f2e93bSKazutaka YOKOTA 	int y;
12802f2e93bSKazutaka YOKOTA 
12902f2e93bSKazutaka YOKOTA 	if (xlen <= 0)
13002f2e93bSKazutaka YOKOTA 		return;
13102f2e93bSKazutaka YOKOTA 	for (y = yoff; y < ylen; y++)
13202f2e93bSKazutaka YOKOTA 		fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
13302f2e93bSKazutaka YOKOTA 		      CONSOLE_VECT(xpos + xoff, ypos + y), xlen - xoff);
13402f2e93bSKazutaka YOKOTA }
13502f2e93bSKazutaka YOKOTA 
13602f2e93bSKazutaka YOKOTA static void
13702f2e93bSKazutaka YOKOTA draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
13802f2e93bSKazutaka YOKOTA 	    int xlen, int ylen)
139e8adebf2SKazutaka YOKOTA {
140e8adebf2SKazutaka YOKOTA 	int x, y;
14102f2e93bSKazutaka YOKOTA 	int px;
142e8adebf2SKazutaka YOKOTA 	int attr;
143e8adebf2SKazutaka YOKOTA 
14402f2e93bSKazutaka YOKOTA 	for (y = yoff; y < ylen; y++) {
14502f2e93bSKazutaka YOKOTA 		if (dxdir < 0)
14602f2e93bSKazutaka YOKOTA 			px = xoff;
14702f2e93bSKazutaka YOKOTA 		else
14802f2e93bSKazutaka YOKOTA 			px = DAEMON_MAX_WIDTH - xlen;
14902f2e93bSKazutaka YOKOTA 		if (px >= strlen(daemon_pic[y]))
15002f2e93bSKazutaka YOKOTA 			continue;
15102f2e93bSKazutaka YOKOTA 		for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) {
15202f2e93bSKazutaka YOKOTA 			switch (daemon_attr[y][px]) {
153e8adebf2SKazutaka YOKOTA 			case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break;
154e8adebf2SKazutaka YOKOTA 			case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break;
155e8adebf2SKazutaka YOKOTA 			case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break;
156e8adebf2SKazutaka YOKOTA 			case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
157e8adebf2SKazutaka YOKOTA 			case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
158e8adebf2SKazutaka YOKOTA 			default: attr = (FG_WHITE|BG_BLACK)<<8; break;
159e8adebf2SKazutaka YOKOTA 			}
160068eabc6SKazutaka YOKOTA 			if (dxdir < 0) {	/* Moving left */
16102f2e93bSKazutaka YOKOTA 				*CONSOLE_VECT(xpos + x, ypos + y) =
16202f2e93bSKazutaka YOKOTA 					scr_map[daemon_pic[y][px]]|attr;
163068eabc6SKazutaka YOKOTA 			} else {		/* Moving right */
16402f2e93bSKazutaka YOKOTA 				*CONSOLE_VECT(xpos + DAEMON_MAX_WIDTH - px - 1, ypos + y) =
16502f2e93bSKazutaka YOKOTA 					scr_map[xflip_symbol(daemon_pic[y][px])]|attr;
16602f2e93bSKazutaka YOKOTA 			}
167068eabc6SKazutaka YOKOTA 		}
168e8adebf2SKazutaka YOKOTA 	}
169e8adebf2SKazutaka YOKOTA }
170e8adebf2SKazutaka YOKOTA 
171e8adebf2SKazutaka YOKOTA static void
17202f2e93bSKazutaka YOKOTA clear_string(int xpos, int ypos, int xoff, char *s, int len)
17302f2e93bSKazutaka YOKOTA {
17402f2e93bSKazutaka YOKOTA 	if (len <= 0)
17502f2e93bSKazutaka YOKOTA 		return;
17602f2e93bSKazutaka YOKOTA 	fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
17702f2e93bSKazutaka YOKOTA 	      CONSOLE_VECT(xpos + xoff, ypos), len - xoff);
17802f2e93bSKazutaka YOKOTA }
17902f2e93bSKazutaka YOKOTA 
18002f2e93bSKazutaka YOKOTA static void
18102f2e93bSKazutaka YOKOTA draw_string(int xpos, int ypos, int xoff, char *s, int len)
182e8adebf2SKazutaka YOKOTA {
183e8adebf2SKazutaka YOKOTA 	int x;
184e8adebf2SKazutaka YOKOTA 
18502f2e93bSKazutaka YOKOTA 	for (x = xoff; x < len; x++)
18602f2e93bSKazutaka YOKOTA 		*CONSOLE_VECT(xpos + x, ypos) =
187e8adebf2SKazutaka YOKOTA 			scr_map[s[x]]|(FG_LIGHTGREEN|BG_BLACK)<<8;
188e8adebf2SKazutaka YOKOTA }
189e8adebf2SKazutaka YOKOTA 
190e8adebf2SKazutaka YOKOTA static void
191e8adebf2SKazutaka YOKOTA daemon_saver(int blank)
192e8adebf2SKazutaka YOKOTA {
193e8adebf2SKazutaka YOKOTA 	static int txpos = 10, typos = 10;
194e8adebf2SKazutaka YOKOTA 	static int txdir = -1, tydir = -1;
195068eabc6SKazutaka YOKOTA 	static int dxpos = 0, dypos = 0;
196068eabc6SKazutaka YOKOTA 	static int dxdir = 1, dydir = 1;
197e8adebf2SKazutaka YOKOTA 	static int moved_daemon = 0;
19802f2e93bSKazutaka YOKOTA 	static int xoff, yoff, toff;
19902f2e93bSKazutaka YOKOTA 	static int xlen, ylen, tlen;
200e8adebf2SKazutaka YOKOTA 	scr_stat *scp = cur_console;
20102f2e93bSKazutaka YOKOTA 	int min, max;
202e8adebf2SKazutaka YOKOTA 
203e8adebf2SKazutaka YOKOTA 	if (blank) {
20402f2e93bSKazutaka YOKOTA 		if (scrn_blanked == 0) {
20502f2e93bSKazutaka YOKOTA 			/* clear the screen and set the border color */
20602f2e93bSKazutaka YOKOTA 			fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
20702f2e93bSKazutaka YOKOTA 			      Crtat, scp->xsize * scp->ysize);
20802f2e93bSKazutaka YOKOTA 			set_border(0);
20902f2e93bSKazutaka YOKOTA 			xlen = ylen = tlen = 0;
21002f2e93bSKazutaka YOKOTA 		}
211e8adebf2SKazutaka YOKOTA 		if (scrn_blanked++ < 2)
212e8adebf2SKazutaka YOKOTA 			return;
213e8adebf2SKazutaka YOKOTA 		scrn_blanked = 1;
214e8adebf2SKazutaka YOKOTA 
21502f2e93bSKazutaka YOKOTA  		clear_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
21602f2e93bSKazutaka YOKOTA 		clear_string(txpos, typos, toff, (char *)message, tlen);
21702f2e93bSKazutaka YOKOTA 
218e8adebf2SKazutaka YOKOTA 		if (++moved_daemon) {
21902f2e93bSKazutaka YOKOTA 			/*
22002f2e93bSKazutaka YOKOTA 			 * The daemon picture may be off the screen, if
22102f2e93bSKazutaka YOKOTA 			 * screen size is chagened while the screen
22202f2e93bSKazutaka YOKOTA 			 * saver is inactive. Make sure the origin of
22302f2e93bSKazutaka YOKOTA 			 * the picture is between min and max.
22402f2e93bSKazutaka YOKOTA 			 */
22502f2e93bSKazutaka YOKOTA 			if (scp->xsize <= DAEMON_MAX_WIDTH) {
22602f2e93bSKazutaka YOKOTA 				/*
22702f2e93bSKazutaka YOKOTA 				 * If the screen width is too narrow, we
22802f2e93bSKazutaka YOKOTA 				 * allow part of the picture go off
22902f2e93bSKazutaka YOKOTA 				 * the screen so that the daemon won't
23002f2e93bSKazutaka YOKOTA 				 * flip too often.
23102f2e93bSKazutaka YOKOTA 				 */
23202f2e93bSKazutaka YOKOTA 				min = scp->xsize - DAEMON_MAX_WIDTH - 10;
23302f2e93bSKazutaka YOKOTA 				max = 10;
23402f2e93bSKazutaka YOKOTA 			} else {
23502f2e93bSKazutaka YOKOTA 				min = 0;
23602f2e93bSKazutaka YOKOTA 				max = scp->xsize - DAEMON_MAX_WIDTH;
23702f2e93bSKazutaka YOKOTA 			}
23802f2e93bSKazutaka YOKOTA 			if (dxpos <= min) {
23902f2e93bSKazutaka YOKOTA 				dxpos = min;
24002f2e93bSKazutaka YOKOTA 				dxdir = 1;
24102f2e93bSKazutaka YOKOTA 			} else if (dxpos >= max) {
24202f2e93bSKazutaka YOKOTA 				dxpos = max;
243e8adebf2SKazutaka YOKOTA 				dxdir = -1;
244e8adebf2SKazutaka YOKOTA 			}
245e8adebf2SKazutaka YOKOTA 
24602f2e93bSKazutaka YOKOTA 			if (scp->ysize <= DAEMON_MAX_HEIGHT) {
24702f2e93bSKazutaka YOKOTA 				min = scp->ysize - DAEMON_MAX_HEIGHT - 10;
24802f2e93bSKazutaka YOKOTA 				max = 10;
249e8adebf2SKazutaka YOKOTA 			} else {
25002f2e93bSKazutaka YOKOTA 				min = 0;
25102f2e93bSKazutaka YOKOTA 				max = scp->ysize - DAEMON_MAX_HEIGHT;
252e8adebf2SKazutaka YOKOTA 			}
25302f2e93bSKazutaka YOKOTA 			if (dypos <= min) {
25402f2e93bSKazutaka YOKOTA 				dypos = min;
25502f2e93bSKazutaka YOKOTA 				dydir = 1;
25602f2e93bSKazutaka YOKOTA 			} else if (dypos >= max) {
25702f2e93bSKazutaka YOKOTA 				dypos = max;
25802f2e93bSKazutaka YOKOTA 				dydir = -1;
25902f2e93bSKazutaka YOKOTA 			}
26002f2e93bSKazutaka YOKOTA 
26102f2e93bSKazutaka YOKOTA 			moved_daemon = -1;
26202f2e93bSKazutaka YOKOTA 			dxpos += dxdir; dypos += dydir;
26302f2e93bSKazutaka YOKOTA 
26402f2e93bSKazutaka YOKOTA 			/* clip the picture */
26502f2e93bSKazutaka YOKOTA 			xoff = 0;
26602f2e93bSKazutaka YOKOTA 			xlen = DAEMON_MAX_WIDTH;
26702f2e93bSKazutaka YOKOTA 			if (dxpos + xlen <= 0)
26802f2e93bSKazutaka YOKOTA 				xlen = 0;
26902f2e93bSKazutaka YOKOTA 			else if (dxpos < 0)
27002f2e93bSKazutaka YOKOTA 				xoff = -dxpos;
27102f2e93bSKazutaka YOKOTA 			if (dxpos >= scp->xsize)
27202f2e93bSKazutaka YOKOTA 				xlen = 0;
27302f2e93bSKazutaka YOKOTA 			else if (dxpos + xlen > scp->xsize)
27402f2e93bSKazutaka YOKOTA 				xlen = scp->xsize - dxpos;
27502f2e93bSKazutaka YOKOTA 			yoff = 0;
27602f2e93bSKazutaka YOKOTA 			ylen = DAEMON_MAX_HEIGHT;
27702f2e93bSKazutaka YOKOTA 			if (dypos + ylen <= 0)
27802f2e93bSKazutaka YOKOTA 				ylen = 0;
27902f2e93bSKazutaka YOKOTA 			else if (dypos < 0)
28002f2e93bSKazutaka YOKOTA 				yoff = -dypos;
28102f2e93bSKazutaka YOKOTA 			if (dypos >= scp->ysize)
28202f2e93bSKazutaka YOKOTA 				ylen = 0;
28302f2e93bSKazutaka YOKOTA 			else if (dypos + ylen > scp->ysize)
28402f2e93bSKazutaka YOKOTA 				ylen = scp->ysize - dypos;
28502f2e93bSKazutaka YOKOTA 		}
28602f2e93bSKazutaka YOKOTA 
28702f2e93bSKazutaka YOKOTA 		if (scp->xsize <= messagelen) {
28802f2e93bSKazutaka YOKOTA 			min = scp->xsize - messagelen - 10;
28902f2e93bSKazutaka YOKOTA 			max = 10;
290e8adebf2SKazutaka YOKOTA 		} else {
29102f2e93bSKazutaka YOKOTA 			min = 0;
29202f2e93bSKazutaka YOKOTA 			max = scp->xsize - messagelen;
29302f2e93bSKazutaka YOKOTA 		}
29402f2e93bSKazutaka YOKOTA 		if (txpos <= min) {
29502f2e93bSKazutaka YOKOTA 			txpos = min;
29602f2e93bSKazutaka YOKOTA 			txdir = 1;
29702f2e93bSKazutaka YOKOTA 		} else if (txpos >= max) {
29802f2e93bSKazutaka YOKOTA 			txpos = max;
29902f2e93bSKazutaka YOKOTA 			txdir = -1;
30002f2e93bSKazutaka YOKOTA 		}
30102f2e93bSKazutaka YOKOTA 		if (typos <= 0) {
30202f2e93bSKazutaka YOKOTA 			typos = 0;
30302f2e93bSKazutaka YOKOTA 			tydir = 1;
30402f2e93bSKazutaka YOKOTA 		} else if (typos >= scp->ysize - 1) {
30502f2e93bSKazutaka YOKOTA 			typos = scp->ysize - 1;
30602f2e93bSKazutaka YOKOTA 			tydir = -1;
307e8adebf2SKazutaka YOKOTA 		}
308e8adebf2SKazutaka YOKOTA 		txpos += txdir; typos += tydir;
309e8adebf2SKazutaka YOKOTA 
31002f2e93bSKazutaka YOKOTA 		toff = 0;
31102f2e93bSKazutaka YOKOTA 		tlen = messagelen;
31202f2e93bSKazutaka YOKOTA 		if (txpos + tlen <= 0)
31302f2e93bSKazutaka YOKOTA 			tlen = 0;
31402f2e93bSKazutaka YOKOTA 		else if (txpos < 0)
31502f2e93bSKazutaka YOKOTA 			toff = -txpos;
31602f2e93bSKazutaka YOKOTA 		if (txpos >= scp->xsize)
31702f2e93bSKazutaka YOKOTA 			tlen = 0;
31802f2e93bSKazutaka YOKOTA 		else if (txpos + tlen > scp->xsize)
31902f2e93bSKazutaka YOKOTA 			tlen = scp->xsize - txpos;
32002f2e93bSKazutaka YOKOTA 
32102f2e93bSKazutaka YOKOTA  		draw_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
32202f2e93bSKazutaka YOKOTA 		draw_string(txpos, typos, toff, (char *)message, tlen);
323e8adebf2SKazutaka YOKOTA 	} else {
324ce834215SKazutaka YOKOTA 		if (scrn_blanked > 0) {
325e8adebf2SKazutaka YOKOTA 			set_border(scp->border);
326e8adebf2SKazutaka YOKOTA 			scrn_blanked = 0;
327e8adebf2SKazutaka YOKOTA 		}
328e8adebf2SKazutaka YOKOTA 	}
329e8adebf2SKazutaka YOKOTA }
330e8adebf2SKazutaka YOKOTA 
331e8adebf2SKazutaka YOKOTA static int
332e8adebf2SKazutaka YOKOTA daemon_saver_load(struct lkm_table *lkmtp, int cmd)
333e8adebf2SKazutaka YOKOTA {
334ce834215SKazutaka YOKOTA 	int err;
335f4863d1aSKazutaka YOKOTA 
336ce834215SKazutaka YOKOTA 	messagelen = strlen(hostname) + 3 + strlen(ostype) + 1 +
337ce834215SKazutaka YOKOTA 	    strlen(osrelease);
338ce834215SKazutaka YOKOTA 	message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK);
339ce834215SKazutaka YOKOTA 	sprintf(message, "%s - %s %s", hostname, ostype, osrelease);
340f4863d1aSKazutaka YOKOTA 
341ce834215SKazutaka YOKOTA 	err = add_scrn_saver(daemon_saver);
342ce834215SKazutaka YOKOTA 	if (err != 0)
343ce834215SKazutaka YOKOTA 		free(message, M_DEVBUF);
344ce834215SKazutaka YOKOTA 	return err;
345e8adebf2SKazutaka YOKOTA }
346e8adebf2SKazutaka YOKOTA 
347e8adebf2SKazutaka YOKOTA static int
348e8adebf2SKazutaka YOKOTA daemon_saver_unload(struct lkm_table *lkmtp, int cmd)
349e8adebf2SKazutaka YOKOTA {
350ce834215SKazutaka YOKOTA 	int err;
351f4863d1aSKazutaka YOKOTA 
352ce834215SKazutaka YOKOTA 	err = remove_scrn_saver(daemon_saver);
353ce834215SKazutaka YOKOTA 	if (err == 0)
354f4863d1aSKazutaka YOKOTA 		free(message, M_DEVBUF);
355ce834215SKazutaka YOKOTA 	return err;
356e8adebf2SKazutaka YOKOTA }
357e8adebf2SKazutaka YOKOTA 
358e8adebf2SKazutaka YOKOTA int
359e8adebf2SKazutaka YOKOTA daemon_saver_mod(struct lkm_table *lkmtp, int cmd, int ver)
360e8adebf2SKazutaka YOKOTA {
3618800a82cSKazutaka YOKOTA 	MOD_DISPATCH(daemon_saver, lkmtp, cmd, ver,
3628800a82cSKazutaka YOKOTA 		daemon_saver_load, daemon_saver_unload, lkm_nullcmd);
363e8adebf2SKazutaka YOKOTA }
364