daemon_saver.c revision 26128
1/*-
2 * Copyright (c) 1997 Sandro Sigala, Brescia, Italy.
3 * Copyright (c) 1997 Chris Shenton
4 * Copyright (c) 1995 S ren Schmidt
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
16 *
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.
27 *
28 *	$Id: daemon_saver.c,v 1.2 1997/05/24 01:44:39 yokota Exp $
29 */
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/conf.h>
34#include <sys/exec.h>
35#include <sys/sysent.h>
36#include <sys/lkm.h>
37#include <sys/errno.h>
38
39#include <machine/md_var.h>
40
41#include "saver.h"
42
43MOD_MISC(daemon_saver);
44
45void (*current_saver)(int blank);
46void (*old_saver)(int blank);
47
48#define CONSOLE_VECT(x, y) \
49	*((u_short*)(Crtat + (y)*cur_console->xsize + (x)))
50
51#define DAEMON_MAX_WIDTH	32
52#define DAEMON_MAX_HEIGHT	19
53
54/*
55 * Define this to disable the bouncing text.
56 */
57#undef DAEMON_ONLY
58
59/* Who is the author of this ASCII pic? */
60
61static char *daemon_pic[] = {
62        "             ,        ,",
63	"            /(        )`",
64	"            \\ \\___   / |",
65	"            /- _  `-/  '",
66	"           (/\\/ \\ \\   /\\",
67	"           / /   | `    \\",
68	"           O O   ) /    |",
69	"           `-^--'`<     '",
70	"          (_.)  _  )   /",
71	"           `.___/`    /",
72	"             `-----' /",
73	"<----.     __ / __   \\",
74	"<----|====O)))==) \\) /====",
75	"<----'    `--' `.__,' \\",
76	"             |        |",
77	"              \\       /       /\\",
78	"         ______( (_  / \\______/",
79	"       ,'  ,-----'   |",
80	"       `--{__________)",
81	NULL
82};
83
84static char *daemon_attr[] = {
85        "             R        R",
86	"            RR        RR",
87	"            R RRRR   R R",
88	"            RR W  RRR  R",
89	"           RWWW W R   RR",
90	"           W W   W R    R",
91	"           B B   W R    R",
92	"           WWWWWWRR     R",
93	"          RRRR  R  R   R",
94	"           RRRRRRR    R",
95	"             RRRRRRR R",
96	"YYYYYY     RR R RR   R",
97	"YYYYYYYYYYRRRRYYR RR RYYYY",
98	"YYYYYY    RRRR RRRRRR R",
99	"             R        R",
100	"              R       R       RR",
101	"         CCCCCCR RR  R RRRRRRRR",
102	"       CC  CCCCCCC   C",
103	"       CCCCCCCCCCCCCCC",
104	NULL
105};
106
107/*
108 * Reverse a graphics character, or return unaltered if no mirror;
109 * should do alphanumerics too, but I'm too lazy. <cshenton@it.hq.nasa.gov>
110 */
111
112static char
113xflip_symbol(char symbol)
114{
115	static const char lchars[] = "`'(){}[]\\/<>";
116	static const char rchars[] = "'`)(}{][/\\><";
117	int pos;
118
119	for (pos = 0; lchars[pos] != '\0'; pos++)
120		if (lchars[pos] == symbol)
121			return rchars[pos];
122
123	return symbol;
124}
125
126static void
127draw_daemon(int xpos, int ypos, int dxdir)
128{
129	int x, y;
130	int attr;
131
132	for (y = 0; daemon_pic[y] != NULL; y++)
133		for (x = 0; daemon_pic[y][x] != '\0'; x++) {
134			switch (daemon_attr[y][x]) {
135			case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break;
136			case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break;
137			case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break;
138			case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
139			case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
140			default: attr = (FG_WHITE|BG_BLACK)<<8; break;
141			}
142			if (dxdir < 0) {	/* Moving left */
143				CONSOLE_VECT(xpos + x, ypos + y) =
144					scr_map[daemon_pic[y][x]]|attr;
145			} else {		/* Moving right */
146				CONSOLE_VECT(xpos + DAEMON_MAX_WIDTH - x - 1, ypos + y) =
147					scr_map[xflip_symbol(daemon_pic[y][x])]|attr;
148			}
149		}
150}
151
152#ifndef DAEMON_ONLY
153static void
154draw_string(int xpos, int ypos, char *s, int len)
155{
156	int x;
157
158	for (x = 0; x < len; x++)
159		CONSOLE_VECT(xpos + x, ypos) =
160			scr_map[s[x]]|(FG_LIGHTGREEN|BG_BLACK)<<8;
161}
162#endif
163
164static void
165daemon_saver(int blank)
166{
167#ifndef DAEMON_ONLY
168	static const char message[] = {"FreeBSD 2.2 STABLE"};
169	static int txpos = 10, typos = 10;
170	static int txdir = -1, tydir = -1;
171#endif
172	static int dxpos = 0, dypos = 0;
173	static int dxdir = 1, dydir = 1;
174	static int moved_daemon = 0;
175	scr_stat *scp = cur_console;
176
177	if (blank) {
178		if (scrn_blanked++ < 2)
179			return;
180		fillw((FG_LIGHTGREY|BG_BLACK)<<8|scr_map[0x20], Crtat,
181		      scp->xsize * scp->ysize);
182		set_border(0);
183		scrn_blanked = 1;
184
185		if (++moved_daemon) {
186			if (dxdir > 0) {
187				if (dxpos == scp->xsize - DAEMON_MAX_WIDTH)
188					dxdir = -1;
189			} else {
190				if (dxpos == 0) dxdir = 1;
191			}
192			if (dydir > 0) {
193				if (dypos == scp->ysize - DAEMON_MAX_HEIGHT)
194					dydir = -1;
195			} else {
196				if (dypos == 0) dydir = 1;
197			}
198			moved_daemon = -1;
199			dxpos += dxdir; dypos += dydir;
200		}
201
202#ifndef DAEMON_ONLY
203		if (txdir > 0) {
204			if (txpos == scp->xsize - sizeof(message)-1)
205				txdir = -1;
206		} else {
207			if (txpos == 0) txdir = 1;
208		}
209		if (tydir > 0) {
210			if (typos == scp->ysize - 1)
211				tydir = -1;
212		} else {
213			if (typos == 0) tydir = 1;
214		}
215		txpos += txdir; typos += tydir;
216#endif
217
218 		draw_daemon(dxpos, dypos, dxdir);
219#ifndef DAEMON_ONLY
220		draw_string(txpos, typos, (char *)message, sizeof(message)-1);
221#endif
222	} else {
223		if (scrn_blanked) {
224			set_border(scp->border);
225			scrn_blanked = 0;
226			scp->start = 0;
227			scp->end = scp->xsize * scp->ysize;
228		}
229	}
230}
231
232static int
233daemon_saver_load(struct lkm_table *lkmtp, int cmd)
234{
235	(*current_saver)(0);
236	old_saver = current_saver;
237	current_saver = daemon_saver;
238	return 0;
239}
240
241static int
242daemon_saver_unload(struct lkm_table *lkmtp, int cmd)
243{
244	(*current_saver)(0);
245	current_saver = old_saver;
246	return 0;
247}
248
249int
250daemon_saver_mod(struct lkm_table *lkmtp, int cmd, int ver)
251{
252	DISPATCH(lkmtp, cmd, ver, daemon_saver_load, daemon_saver_unload,
253		 lkm_nullcmd);
254}
255