Scrap PC98 support.
[dragonfly.git] / sys / dev / misc / syscons / daemon / daemon_saver.c
CommitLineData
984263bc
MD
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 * $FreeBSD: src/sys/modules/syscons/daemon/daemon_saver.c,v 1.18.2.2 2001/05/06 05:44:29 nyan Exp $
7aa7bdf5 29 * $DragonFly: src/sys/dev/misc/syscons/daemon/Attic/daemon_saver.c,v 1.4 2005/02/13 03:02:25 swildner Exp $
984263bc
MD
30 */
31
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>
39#include <sys/fbio.h>
40
41#include <machine/pc/display.h>
42
ac2e3f5e
MD
43#include <dev/video/fb/fbreg.h>
44#include <dev/video/fb/splashreg.h>
45#include "../syscons.h"
984263bc 46
984263bc
MD
47#define DAEMON_MAX_WIDTH 32
48#define DAEMON_MAX_HEIGHT 19
49
50static u_char *message;
51static int messagelen;
52static int blanked;
53
54/* Who is the author of this ASCII pic? */
55
56static u_char *daemon_pic[] = {
57 " , ,",
58 " /( )`",
59 " \\ \\___ / |",
60 " /- _ `-/ '",
61 " (/\\/ \\ \\ /\\",
62 " / / | ` \\",
63 " O O ) / |",
64 " `-^--'`< '",
65 " (_.) _ ) /",
66 " `.___/` /",
67 " `-----' /",
68 "<----. __ / __ \\",
69 "<----|====O)))==) \\) /====",
70 "<----' `--' `.__,' \\",
71 " | |",
72 " \\ / /\\",
73 " ______( (_ / \\______/",
74 " ,' ,-----' |",
75 " `--{__________)",
76 NULL
77};
78
79static u_char *daemon_attr[] = {
80 " R R",
81 " RR RR",
82 " R RRRR R R",
83 " RR W RRR R",
84 " RWWW W R RR",
85 " W W W R R",
86 " B B W R R",
87 " WWWWWWRR R",
88 " RRRR R R R",
89 " RRRRRRR R",
90 " RRRRRRR R",
91 "YYYYYY RR R RR R",
92 "YYYYYYYYYYRRRRYYR RR RYYYY",
93 "YYYYYY RRRR RRRRRR R",
94 " R R",
95 " R R RR",
96 " CCCCCCR RR R RRRRRRRR",
97 " CC CCCCCCC C",
98 " CCCCCCCCCCCCCCC",
99 NULL
100};
101
102/*
103 * Reverse a graphics character, or return unaltered if no mirror;
104 * should do alphanumerics too, but I'm too lazy. <cshenton@it.hq.nasa.gov>
105 */
106
107static u_char
108xflip_symbol(u_char symbol)
109{
110 static const u_char lchars[] = "`'(){}[]\\/<>";
111 static const u_char rchars[] = "'`)(}{][/\\><";
112 int pos;
113
114 for (pos = 0; lchars[pos] != '\0'; pos++)
115 if (lchars[pos] == symbol)
116 return rchars[pos];
117
118 return symbol;
119}
120
121static void
122clear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
123 int xlen, int ylen)
124{
125 int y;
126
127 if (xlen <= 0)
128 return;
129 for (y = yoff; y < ylen; y++) {
130 sc_vtb_erase(&sc->cur_scp->scr,
131 (ypos + y)*sc->cur_scp->xsize + xpos + xoff,
132 xlen - xoff,
133 sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
134 }
135}
136
137static void
138draw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
139 int xlen, int ylen)
140{
141 int x, y;
142 int px;
143 int attr;
144
145 for (y = yoff; y < ylen; y++) {
146 if (dxdir < 0)
147 px = xoff;
148 else
149 px = DAEMON_MAX_WIDTH - xlen;
150 if (px >= strlen(daemon_pic[y]))
151 continue;
152 for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) {
153 switch (daemon_attr[y][px]) {
984263bc
MD
154 case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break;
155 case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break;
156 case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break;
157 case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
158 case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
159 default: attr = (FG_WHITE|BG_BLACK)<<8; break;
984263bc
MD
160 }
161 if (dxdir < 0) { /* Moving left */
162 sc_vtb_putc(&sc->cur_scp->scr,
163 (ypos + y)*sc->cur_scp->xsize
164 + xpos + x,
165 sc->scr_map[daemon_pic[y][px]],
166 attr);
167 } else { /* Moving right */
168 sc_vtb_putc(&sc->cur_scp->scr,
169 (ypos + y)*sc->cur_scp->xsize
170 + xpos + DAEMON_MAX_WIDTH
171 - px - 1,
172 sc->scr_map[xflip_symbol(daemon_pic[y][px])],
173 attr);
174 }
175 }
176 }
177}
178
179static void
180clear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len)
181{
182 if (len <= 0)
183 return;
184 sc_vtb_erase(&sc->cur_scp->scr,
185 ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff,
186 sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
187}
188
189static void
190draw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, u_char *s, int len)
191{
192 int x;
193
194 for (x = xoff; x < len; x++) {
984263bc
MD
195 sc_vtb_putc(&sc->cur_scp->scr,
196 ypos*sc->cur_scp->xsize + xpos + x,
197 sc->scr_map[s[x]], (FG_LIGHTGREEN | BG_BLACK) << 8);
984263bc
MD
198 }
199}
200
201static int
202daemon_saver(video_adapter_t *adp, int blank)
203{
204 static int txpos = 10, typos = 10;
205 static int txdir = -1, tydir = -1;
206 static int dxpos = 0, dypos = 0;
207 static int dxdir = 1, dydir = 1;
208 static int moved_daemon = 0;
209 static int xoff, yoff, toff;
210 static int xlen, ylen, tlen;
211 sc_softc_t *sc;
212 scr_stat *scp;
213 int min, max;
214
215 sc = sc_find_softc(adp, NULL);
216 if (sc == NULL)
217 return EAGAIN;
218 scp = sc->cur_scp;
219
220 if (blank) {
221 if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
222 return EAGAIN;
223 if (blanked == 0) {
984263bc
MD
224 /* clear the screen and set the border color */
225 sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
226 (FG_LIGHTGREY | BG_BLACK) << 8);
227 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
228 sc_set_border(scp, 0);
229 xlen = ylen = tlen = 0;
230 }
231 if (blanked++ < 2)
232 return 0;
233 blanked = 1;
234
235 clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
236 clear_string(sc, txpos, typos, toff, message, tlen);
237
238 if (++moved_daemon) {
239 /*
240 * The daemon picture may be off the screen, if
241 * screen size is chagened while the screen
242 * saver is inactive. Make sure the origin of
243 * the picture is between min and max.
244 */
245 if (scp->xsize <= DAEMON_MAX_WIDTH) {
246 /*
247 * If the screen width is too narrow, we
248 * allow part of the picture go off
249 * the screen so that the daemon won't
250 * flip too often.
251 */
252 min = scp->xsize - DAEMON_MAX_WIDTH - 10;
253 max = 10;
254 } else {
255 min = 0;
256 max = scp->xsize - DAEMON_MAX_WIDTH;
257 }
258 if (dxpos <= min) {
259 dxpos = min;
260 dxdir = 1;
261 } else if (dxpos >= max) {
262 dxpos = max;
263 dxdir = -1;
264 }
265
266 if (scp->ysize <= DAEMON_MAX_HEIGHT) {
267 min = scp->ysize - DAEMON_MAX_HEIGHT - 10;
268 max = 10;
269 } else {
270 min = 0;
271 max = scp->ysize - DAEMON_MAX_HEIGHT;
272 }
273 if (dypos <= min) {
274 dypos = min;
275 dydir = 1;
276 } else if (dypos >= max) {
277 dypos = max;
278 dydir = -1;
279 }
280
281 moved_daemon = -1;
282 dxpos += dxdir; dypos += dydir;
283
284 /* clip the picture */
285 xoff = 0;
286 xlen = DAEMON_MAX_WIDTH;
287 if (dxpos + xlen <= 0)
288 xlen = 0;
289 else if (dxpos < 0)
290 xoff = -dxpos;
291 if (dxpos >= scp->xsize)
292 xlen = 0;
293 else if (dxpos + xlen > scp->xsize)
294 xlen = scp->xsize - dxpos;
295 yoff = 0;
296 ylen = DAEMON_MAX_HEIGHT;
297 if (dypos + ylen <= 0)
298 ylen = 0;
299 else if (dypos < 0)
300 yoff = -dypos;
301 if (dypos >= scp->ysize)
302 ylen = 0;
303 else if (dypos + ylen > scp->ysize)
304 ylen = scp->ysize - dypos;
305 }
306
307 if (scp->xsize <= messagelen) {
308 min = scp->xsize - messagelen - 10;
309 max = 10;
310 } else {
311 min = 0;
312 max = scp->xsize - messagelen;
313 }
314 if (txpos <= min) {
315 txpos = min;
316 txdir = 1;
317 } else if (txpos >= max) {
318 txpos = max;
319 txdir = -1;
320 }
321 if (typos <= 0) {
322 typos = 0;
323 tydir = 1;
324 } else if (typos >= scp->ysize - 1) {
325 typos = scp->ysize - 1;
326 tydir = -1;
327 }
328 txpos += txdir; typos += tydir;
329
330 toff = 0;
331 tlen = messagelen;
332 if (txpos + tlen <= 0)
333 tlen = 0;
334 else if (txpos < 0)
335 toff = -txpos;
336 if (txpos >= scp->xsize)
337 tlen = 0;
338 else if (txpos + tlen > scp->xsize)
339 tlen = scp->xsize - txpos;
340
341 draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
342 draw_string(sc, txpos, typos, toff, message, tlen);
343 } else {
984263bc
MD
344 blanked = 0;
345 }
346 return 0;
347}
348
349static int
350daemon_init(video_adapter_t *adp)
351{
352 messagelen = strlen(hostname) + 3 + strlen(ostype) + 1 +
353 strlen(osrelease);
354 message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK);
355 sprintf(message, "%s - %s %s", hostname, ostype, osrelease);
356 blanked = 0;
357 return 0;
358}
359
360static int
361daemon_term(video_adapter_t *adp)
362{
363 free(message, M_DEVBUF);
364 return 0;
365}
366
367static scrn_saver_t daemon_module = {
368 "daemon_saver", daemon_init, daemon_term, daemon_saver, NULL,
369};
370
371SAVER_MODULE(daemon_saver, daemon_module);