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/fred/fred_saver.c,v 1.7 2006/12/20 18:14:39 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"
47 #define DAEMON_MAX_WIDTH 32
48 #define DAEMON_MAX_HEIGHT 19
50 static u_char
*message
;
51 static int messagelen
;
54 /* Who is the author of this ASCII pic? */
56 static u_char
*daemon_pic
[] = {
69 "<----|====O)))==) \\) /====",
70 "<----' `--' `.__,' \\",
73 " ______( (_ / \\______/",
79 static u_char
*daemon_attr
[] = {
92 "YYYYYYYYYYRRRRYYR RR RYYYY",
93 "YYYYYY RRRR RRRRRR R",
96 " CCCCCCR RR R RRRRRRRR",
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>
108 xflip_symbol(u_char symbol
)
110 static const u_char lchars
[] = "`'(){}[]\\/<>";
111 static const u_char rchars
[] = "'`)(}{][/\\><";
114 for (pos
= 0; lchars
[pos
] != '\0'; pos
++)
115 if (lchars
[pos
] == symbol
)
122 clear_daemon(sc_softc_t
*sc
, int xpos
, int ypos
, int dxdir
, int xoff
, int yoff
,
129 for (y
= yoff
; y
< ylen
; y
++) {
130 sc_vtb_erase(&sc
->cur_scp
->scr
,
131 (ypos
+ y
)*sc
->cur_scp
->xsize
+ xpos
+ xoff
,
133 sc
->scr_map
[0x20], (FG_LIGHTGREY
| BG_BLACK
) << 8);
138 draw_daemon(sc_softc_t
*sc
, int xpos
, int ypos
, int dxdir
, int xoff
, int yoff
,
145 for (y
= yoff
; y
< ylen
; y
++) {
149 px
= DAEMON_MAX_WIDTH
- xlen
;
150 if (px
>= strlen(daemon_pic
[y
]))
152 for (x
= xoff
; (x
< xlen
) && (daemon_pic
[y
][px
] != '\0'); x
++, px
++) {
153 switch (daemon_attr
[y
][px
]) {
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;
161 if (dxdir
< 0) { /* Moving left */
162 sc_vtb_putc(&sc
->cur_scp
->scr
,
163 (ypos
+ y
)*sc
->cur_scp
->xsize
165 sc
->scr_map
[daemon_pic
[y
][px
]],
167 } else { /* Moving right */
168 sc_vtb_putc(&sc
->cur_scp
->scr
,
169 (ypos
+ y
)*sc
->cur_scp
->xsize
170 + xpos
+ DAEMON_MAX_WIDTH
172 sc
->scr_map
[xflip_symbol(daemon_pic
[y
][px
])],
180 clear_string(sc_softc_t
*sc
, int xpos
, int ypos
, int xoff
, char *s
, int len
)
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);
190 draw_string(sc_softc_t
*sc
, int xpos
, int ypos
, int xoff
, u_char
*s
, int len
)
194 for (x
= xoff
; x
< len
; x
++) {
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);
202 daemon_saver(video_adapter_t
*adp
, int blank
)
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
;
215 sc
= sc_find_softc(adp
, NULL
);
221 if (adp
->va_info
.vi_flags
& V_INFO_GRAPHICS
)
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;
235 clear_daemon(sc
, dxpos
, dypos
, dxdir
, xoff
, yoff
, xlen
, ylen
);
236 clear_string(sc
, txpos
, typos
, toff
, message
, tlen
);
238 if (++moved_daemon
) {
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.
245 if (scp
->xsize
<= DAEMON_MAX_WIDTH
) {
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
252 min
= scp
->xsize
- DAEMON_MAX_WIDTH
- 10;
256 max
= scp
->xsize
- DAEMON_MAX_WIDTH
;
261 } else if (dxpos
>= max
) {
266 if (scp
->ysize
<= DAEMON_MAX_HEIGHT
) {
267 min
= scp
->ysize
- DAEMON_MAX_HEIGHT
- 10;
271 max
= scp
->ysize
- DAEMON_MAX_HEIGHT
;
276 } else if (dypos
>= max
) {
282 dxpos
+= dxdir
; dypos
+= dydir
;
284 /* clip the picture */
286 xlen
= DAEMON_MAX_WIDTH
;
287 if (dxpos
+ xlen
<= 0)
291 if (dxpos
>= scp
->xsize
)
293 else if (dxpos
+ xlen
> scp
->xsize
)
294 xlen
= scp
->xsize
- dxpos
;
296 ylen
= DAEMON_MAX_HEIGHT
;
297 if (dypos
+ ylen
<= 0)
301 if (dypos
>= scp
->ysize
)
303 else if (dypos
+ ylen
> scp
->ysize
)
304 ylen
= scp
->ysize
- dypos
;
307 if (scp
->xsize
<= messagelen
) {
308 min
= scp
->xsize
- messagelen
- 10;
312 max
= scp
->xsize
- messagelen
;
317 } else if (txpos
>= max
) {
324 } else if (typos
>= scp
->ysize
- 1) {
325 typos
= scp
->ysize
- 1;
328 txpos
+= txdir
; typos
+= tydir
;
332 if (txpos
+ tlen
<= 0)
336 if (txpos
>= scp
->xsize
)
338 else if (txpos
+ tlen
> scp
->xsize
)
339 tlen
= scp
->xsize
- txpos
;
341 draw_daemon(sc
, dxpos
, dypos
, dxdir
, xoff
, yoff
, xlen
, ylen
);
342 draw_string(sc
, txpos
, typos
, toff
, message
, tlen
);
350 daemon_init(video_adapter_t
*adp
)
352 messagelen
= strlen(hostname
) + 3 + strlen(ostype
) + 1 +
354 message
= kmalloc(messagelen
+ 1, M_SYSCONS
, M_WAITOK
);
355 ksprintf(message
, "%s - %s %s", hostname
, ostype
, osrelease
);
361 daemon_term(video_adapter_t
*adp
)
363 kfree(message
, M_SYSCONS
);
367 static scrn_saver_t daemon_module
= {
368 "daemon_saver", daemon_init
, daemon_term
, daemon_saver
, NULL
,
371 SAVER_MODULE(daemon_saver
, daemon_module
);