2 * Copyright (c) 1997 Sandro Sigala, Brescia, Italy.
3 * Copyright (c) 1997 Chris Shenton
4 * Copyright (c) 1995 S ren Schmidt
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer
12 * in this position and unchanged.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sys/modules/syscons/daemon/daemon_saver.c,v 1.18.2.2 2001/05/06 05:44:29 nyan Exp $
29 * $DragonFly: src/sys/dev/misc/syscons/daemon/Attic/daemon_saver.c,v 1.3 2003/08/15 08:32:29 dillon Exp $
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/module.h>
35 #include <sys/malloc.h>
36 #include <sys/kernel.h>
37 #include <sys/sysctl.h>
38 #include <sys/consio.h>
41 #include <machine/pc/display.h>
43 #include <dev/video/fb/fbreg.h>
44 #include <dev/video/fb/splashreg.h>
45 #include "../syscons.h"
48 #include <pc98/pc98/pc98_machdep.h>
51 #define DAEMON_MAX_WIDTH 32
52 #define DAEMON_MAX_HEIGHT 19
54 static u_char *message;
55 static int messagelen;
58 /* Who is the author of this ASCII pic? */
60 static u_char *daemon_pic[] = {
73 "<----|====O)))==) \\) /====",
74 "<----' `--' `.__,' \\",
77 " ______( (_ / \\______/",
83 static u_char *daemon_attr[] = {
96 "YYYYYYYYYYRRRRYYR RR RYYYY",
97 "YYYYYY RRRR RRRRRR R",
100 " CCCCCCR RR R RRRRRRRR",
107 * Reverse a graphics character, or return unaltered if no mirror;
108 * should do alphanumerics too, but I'm too lazy. <cshenton@it.hq.nasa.gov>
112 xflip_symbol(u_char symbol)
114 static const u_char lchars[] = "`'(){}[]\\/<>";
115 static const u_char rchars[] = "'`)(}{][/\\><";
118 for (pos = 0; lchars[pos] != '\0'; pos++)
119 if (lchars[pos] == symbol)
126 clear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
133 for (y = yoff; y < ylen; y++) {
134 sc_vtb_erase(&sc->cur_scp->scr,
135 (ypos + y)*sc->cur_scp->xsize + xpos + xoff,
137 sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
142 draw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
149 for (y = yoff; y < ylen; y++) {
153 px = DAEMON_MAX_WIDTH - xlen;
154 if (px >= strlen(daemon_pic[y]))
156 for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) {
157 switch (daemon_attr[y][px]) {
159 case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break;
160 case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break;
161 case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break;
162 case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
163 case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
164 default: attr = (FG_WHITE|BG_BLACK)<<8; break;
166 case 'R': attr = (FG_RED|BG_BLACK)<<8; break;
167 case 'Y': attr = (FG_BROWN|BG_BLACK)<<8; break;
168 case 'B': attr = (FG_BLUE|BG_BLACK)<<8; break;
169 case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
170 case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
171 default: attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
174 if (dxdir < 0) { /* Moving left */
175 sc_vtb_putc(&sc->cur_scp->scr,
176 (ypos + y)*sc->cur_scp->xsize
178 sc->scr_map[daemon_pic[y][px]],
180 } else { /* Moving right */
181 sc_vtb_putc(&sc->cur_scp->scr,
182 (ypos + y)*sc->cur_scp->xsize
183 + xpos + DAEMON_MAX_WIDTH
185 sc->scr_map[xflip_symbol(daemon_pic[y][px])],
193 clear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len)
197 sc_vtb_erase(&sc->cur_scp->scr,
198 ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff,
199 sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
203 draw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, u_char *s, int len)
207 for (x = xoff; x < len; x++) {
209 sc_vtb_putc(&sc->cur_scp->scr,
210 ypos*sc->cur_scp->xsize + xpos + x,
211 sc->scr_map[s[x]], (FG_GREEN | BG_BLACK) << 8);
213 sc_vtb_putc(&sc->cur_scp->scr,
214 ypos*sc->cur_scp->xsize + xpos + x,
215 sc->scr_map[s[x]], (FG_LIGHTGREEN | BG_BLACK) << 8);
221 daemon_saver(video_adapter_t *adp, int blank)
223 static int txpos = 10, typos = 10;
224 static int txdir = -1, tydir = -1;
225 static int dxpos = 0, dypos = 0;
226 static int dxdir = 1, dydir = 1;
227 static int moved_daemon = 0;
228 static int xoff, yoff, toff;
229 static int xlen, ylen, tlen;
234 sc = sc_find_softc(adp, NULL);
240 if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
244 if (epson_machine_id == 0x20) {
246 outb(0x0c17, inb(0xc17) & ~0x08);
250 /* clear the screen and set the border color */
251 sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
252 (FG_LIGHTGREY | BG_BLACK) << 8);
253 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
254 sc_set_border(scp, 0);
255 xlen = ylen = tlen = 0;
261 clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
262 clear_string(sc, txpos, typos, toff, message, tlen);
264 if (++moved_daemon) {
266 * The daemon picture may be off the screen, if
267 * screen size is chagened while the screen
268 * saver is inactive. Make sure the origin of
269 * the picture is between min and max.
271 if (scp->xsize <= DAEMON_MAX_WIDTH) {
273 * If the screen width is too narrow, we
274 * allow part of the picture go off
275 * the screen so that the daemon won't
278 min = scp->xsize - DAEMON_MAX_WIDTH - 10;
282 max = scp->xsize - DAEMON_MAX_WIDTH;
287 } else if (dxpos >= max) {
292 if (scp->ysize <= DAEMON_MAX_HEIGHT) {
293 min = scp->ysize - DAEMON_MAX_HEIGHT - 10;
297 max = scp->ysize - DAEMON_MAX_HEIGHT;
302 } else if (dypos >= max) {
308 dxpos += dxdir; dypos += dydir;
310 /* clip the picture */
312 xlen = DAEMON_MAX_WIDTH;
313 if (dxpos + xlen <= 0)
317 if (dxpos >= scp->xsize)
319 else if (dxpos + xlen > scp->xsize)
320 xlen = scp->xsize - dxpos;
322 ylen = DAEMON_MAX_HEIGHT;
323 if (dypos + ylen <= 0)
327 if (dypos >= scp->ysize)
329 else if (dypos + ylen > scp->ysize)
330 ylen = scp->ysize - dypos;
333 if (scp->xsize <= messagelen) {
334 min = scp->xsize - messagelen - 10;
338 max = scp->xsize - messagelen;
343 } else if (txpos >= max) {
350 } else if (typos >= scp->ysize - 1) {
351 typos = scp->ysize - 1;
354 txpos += txdir; typos += tydir;
358 if (txpos + tlen <= 0)
362 if (txpos >= scp->xsize)
364 else if (txpos + tlen > scp->xsize)
365 tlen = scp->xsize - txpos;
367 draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
368 draw_string(sc, txpos, typos, toff, message, tlen);
371 if (epson_machine_id == 0x20) {
373 outb(0x0c17, inb(0xc17) | 0x08);
383 daemon_init(video_adapter_t *adp)
385 messagelen = strlen(hostname) + 3 + strlen(ostype) + 1 +
387 message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK);
388 sprintf(message, "%s - %s %s", hostname, ostype, osrelease);
394 daemon_term(video_adapter_t *adp)
396 free(message, M_DEVBUF);
400 static scrn_saver_t daemon_module = {
401 "daemon_saver", daemon_init, daemon_term, daemon_saver, NULL,
404 SAVER_MODULE(daemon_saver, daemon_module);