daemon_saver.c revision 174985
125968Syokota/*- 225968Syokota * Copyright (c) 1997 Sandro Sigala, Brescia, Italy. 326081Syokota * Copyright (c) 1997 Chris Shenton 425968Syokota * Copyright (c) 1995 S ren Schmidt 525968Syokota * All rights reserved. 625968Syokota * 725968Syokota * Redistribution and use in source and binary forms, with or without 825968Syokota * modification, are permitted provided that the following conditions 925968Syokota * are met: 1025968Syokota * 1. Redistributions of source code must retain the above copyright 1125968Syokota * notice, this list of conditions and the following disclaimer 1225968Syokota * in this position and unchanged. 1325968Syokota * 2. Redistributions in binary form must reproduce the above copyright 1425968Syokota * notice, this list of conditions and the following disclaimer in the 1525968Syokota * documentation and/or other materials provided with the distribution. 1625968Syokota * 1725968Syokota * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1825968Syokota * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1925968Syokota * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2025968Syokota * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2125968Syokota * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2225968Syokota * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2325968Syokota * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2425968Syokota * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2525968Syokota * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2625968Syokota * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2725968Syokota * 2850477Speter * $FreeBSD: head/sys/dev/syscons/daemon/daemon_saver.c 174985 2007-12-29 23:26:59Z wkoszek $ 2925968Syokota */ 3025968Syokota 3125968Syokota#include <sys/param.h> 3225968Syokota#include <sys/systm.h> 3340885Speter#include <sys/module.h> 3427427Syokota#include <sys/malloc.h> 3526893Syokota#include <sys/kernel.h> 3626893Syokota#include <sys/sysctl.h> 3748104Syokota#include <sys/consio.h> 3848104Syokota#include <sys/fbio.h> 3925968Syokota 4032571Sbde#include <machine/pc/display.h> 4125968Syokota 4248104Syokota#include <dev/fb/fbreg.h> 4348104Syokota#include <dev/fb/splashreg.h> 4448104Syokota#include <dev/syscons/syscons.h> 4525968Syokota 4625968Syokota#define DAEMON_MAX_WIDTH 32 4725968Syokota#define DAEMON_MAX_HEIGHT 19 4825968Syokota 4972797Snyanstatic u_char *message; 5027427Syokotastatic int messagelen; 5142504Syokotastatic int blanked; 52146238Snyanstatic int attr_mask; 5327427Syokota 54146238Snyan#define ATTR(attr) (((attr) & attr_mask) << 8) 55146238Snyan 5626081Syokota/* Who is the author of this ASCII pic? */ 5726081Syokota 5872797Snyanstatic u_char *daemon_pic[] = { 5925968Syokota " , ,", 6025968Syokota " /( )`", 6125968Syokota " \\ \\___ / |", 6225968Syokota " /- _ `-/ '", 6325968Syokota " (/\\/ \\ \\ /\\", 6425968Syokota " / / | ` \\", 6525968Syokota " O O ) / |", 6625968Syokota " `-^--'`< '", 6725968Syokota " (_.) _ ) /", 6825968Syokota " `.___/` /", 6925968Syokota " `-----' /", 7025968Syokota "<----. __ / __ \\", 7125968Syokota "<----|====O)))==) \\) /====", 7225968Syokota "<----' `--' `.__,' \\", 7325968Syokota " | |", 7425968Syokota " \\ / /\\", 7525968Syokota " ______( (_ / \\______/", 7625968Syokota " ,' ,-----' |", 7725968Syokota " `--{__________)", 7825968Syokota NULL 7925968Syokota}; 8025968Syokota 8172797Snyanstatic u_char *daemon_attr[] = { 8225968Syokota " R R", 8325968Syokota " RR RR", 8425968Syokota " R RRRR R R", 8525968Syokota " RR W RRR R", 8625968Syokota " RWWW W R RR", 8725968Syokota " W W W R R", 8825968Syokota " B B W R R", 8925968Syokota " WWWWWWRR R", 9025968Syokota " RRRR R R R", 9125968Syokota " RRRRRRR R", 9225968Syokota " RRRRRRR R", 9325968Syokota "YYYYYY RR R RR R", 9425968Syokota "YYYYYYYYYYRRRRYYR RR RYYYY", 9525968Syokota "YYYYYY RRRR RRRRRR R", 9625968Syokota " R R", 9725968Syokota " R R RR", 9825968Syokota " CCCCCCR RR R RRRRRRRR", 9925968Syokota " CC CCCCCCC C", 10025968Syokota " CCCCCCCCCCCCCCC", 10125968Syokota NULL 10225968Syokota}; 10325968Syokota 10426081Syokota/* 10526081Syokota * Reverse a graphics character, or return unaltered if no mirror; 10626081Syokota * should do alphanumerics too, but I'm too lazy. <cshenton@it.hq.nasa.gov> 10726081Syokota */ 10825968Syokota 10972797Snyanstatic u_char 11072797Snyanxflip_symbol(u_char symbol) 11126081Syokota{ 11272797Snyan static const u_char lchars[] = "`'(){}[]\\/<>"; 11372797Snyan static const u_char rchars[] = "'`)(}{][/\\><"; 11426081Syokota int pos; 11526081Syokota 11626081Syokota for (pos = 0; lchars[pos] != '\0'; pos++) 11726081Syokota if (lchars[pos] == symbol) 11826081Syokota return rchars[pos]; 11926081Syokota 12026081Syokota return symbol; 12126081Syokota} 12226081Syokota 12325968Syokotastatic void 12448104Syokotaclear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff, 12530725Syokota int xlen, int ylen) 12625968Syokota{ 12730725Syokota int y; 12830725Syokota 12930725Syokota if (xlen <= 0) 13030725Syokota return; 13148104Syokota for (y = yoff; y < ylen; y++) { 13248104Syokota sc_vtb_erase(&sc->cur_scp->scr, 13348104Syokota (ypos + y)*sc->cur_scp->xsize + xpos + xoff, 13448104Syokota xlen - xoff, 135146238Snyan sc->scr_map[0x20], ATTR(FG_LIGHTGREY | BG_BLACK)); 13648104Syokota } 13730725Syokota} 13830725Syokota 13930725Syokotastatic void 14048104Syokotadraw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff, 14130725Syokota int xlen, int ylen) 14230725Syokota{ 14325968Syokota int x, y; 14430725Syokota int px; 14525968Syokota int attr; 14625968Syokota 14730725Syokota for (y = yoff; y < ylen; y++) { 14830725Syokota if (dxdir < 0) 14930725Syokota px = xoff; 15030725Syokota else 15130725Syokota px = DAEMON_MAX_WIDTH - xlen; 15230725Syokota if (px >= strlen(daemon_pic[y])) 15330725Syokota continue; 15430725Syokota for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) { 15530725Syokota switch (daemon_attr[y][px]) { 156146238Snyan case 'R': attr = FG_LIGHTRED | BG_BLACK; break; 157146238Snyan case 'Y': attr = FG_YELLOW | BG_BLACK; break; 158146238Snyan case 'B': attr = FG_LIGHTBLUE | BG_BLACK; break; 159146238Snyan case 'W': attr = FG_LIGHTGREY | BG_BLACK; break; 160146238Snyan case 'C': attr = FG_CYAN | BG_BLACK; break; 161146238Snyan default: attr = FG_WHITE | BG_BLACK; break; 16225968Syokota } 16326081Syokota if (dxdir < 0) { /* Moving left */ 16448104Syokota sc_vtb_putc(&sc->cur_scp->scr, 16548104Syokota (ypos + y)*sc->cur_scp->xsize 16648104Syokota + xpos + x, 16748104Syokota sc->scr_map[daemon_pic[y][px]], 168146238Snyan ATTR(attr)); 16926081Syokota } else { /* Moving right */ 17048104Syokota sc_vtb_putc(&sc->cur_scp->scr, 17148104Syokota (ypos + y)*sc->cur_scp->xsize 17248104Syokota + xpos + DAEMON_MAX_WIDTH 17348104Syokota - px - 1, 17448104Syokota sc->scr_map[xflip_symbol(daemon_pic[y][px])], 175146238Snyan ATTR(attr)); 17626081Syokota } 17725968Syokota } 17830725Syokota } 17925968Syokota} 18025968Syokota 18125968Syokotastatic void 18248104Syokotaclear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len) 18325968Syokota{ 18430725Syokota if (len <= 0) 18530725Syokota return; 18648104Syokota sc_vtb_erase(&sc->cur_scp->scr, 18748104Syokota ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff, 188146238Snyan sc->scr_map[0x20], ATTR(FG_LIGHTGREY | BG_BLACK)); 18930725Syokota} 19030725Syokota 19130725Syokotastatic void 19272797Snyandraw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, u_char *s, int len) 19330725Syokota{ 19425968Syokota int x; 19525968Syokota 196146238Snyan for (x = xoff; x < len; x++) 19748104Syokota sc_vtb_putc(&sc->cur_scp->scr, 19848104Syokota ypos*sc->cur_scp->xsize + xpos + x, 199146238Snyan sc->scr_map[s[x]], ATTR(FG_LIGHTGREEN | BG_BLACK)); 20025968Syokota} 20125968Syokota 20242504Syokotastatic int 20342504Syokotadaemon_saver(video_adapter_t *adp, int blank) 20425968Syokota{ 20526081Syokota static int txpos = 10, typos = 10; 20626081Syokota static int txdir = -1, tydir = -1; 20725968Syokota static int dxpos = 0, dypos = 0; 20825968Syokota static int dxdir = 1, dydir = 1; 20925968Syokota static int moved_daemon = 0; 21030725Syokota static int xoff, yoff, toff; 21130725Syokota static int xlen, ylen, tlen; 21248104Syokota sc_softc_t *sc; 21348104Syokota scr_stat *scp; 21430725Syokota int min, max; 21525968Syokota 21648104Syokota sc = sc_find_softc(adp, NULL); 21748104Syokota if (sc == NULL) 21848104Syokota return EAGAIN; 21948104Syokota scp = sc->cur_scp; 22048104Syokota 22125968Syokota if (blank) { 22243673Sdes if (adp->va_info.vi_flags & V_INFO_GRAPHICS) 22342749Syokota return EAGAIN; 22442504Syokota if (blanked == 0) { 22530725Syokota /* clear the screen and set the border color */ 22648104Syokota sc_vtb_clear(&scp->scr, sc->scr_map[0x20], 227146238Snyan ATTR(FG_LIGHTGREY | BG_BLACK)); 228174985Swkoszek vidd_set_hw_cursor(adp, -1, -1); 22956043Syokota sc_set_border(scp, 0); 23030725Syokota xlen = ylen = tlen = 0; 23130725Syokota } 23242504Syokota if (blanked++ < 2) 23342504Syokota return 0; 23442504Syokota blanked = 1; 23525968Syokota 23648104Syokota clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); 23772797Snyan clear_string(sc, txpos, typos, toff, message, tlen); 23830725Syokota 23925968Syokota if (++moved_daemon) { 24030725Syokota /* 24130725Syokota * The daemon picture may be off the screen, if 24230725Syokota * screen size is chagened while the screen 24330725Syokota * saver is inactive. Make sure the origin of 24430725Syokota * the picture is between min and max. 24530725Syokota */ 24630725Syokota if (scp->xsize <= DAEMON_MAX_WIDTH) { 24730725Syokota /* 24830725Syokota * If the screen width is too narrow, we 24930725Syokota * allow part of the picture go off 25030725Syokota * the screen so that the daemon won't 25130725Syokota * flip too often. 25230725Syokota */ 25330725Syokota min = scp->xsize - DAEMON_MAX_WIDTH - 10; 25430725Syokota max = 10; 25525968Syokota } else { 25630725Syokota min = 0; 25730725Syokota max = scp->xsize - DAEMON_MAX_WIDTH; 25825968Syokota } 25930725Syokota if (dxpos <= min) { 26030725Syokota dxpos = min; 26130725Syokota dxdir = 1; 26230725Syokota } else if (dxpos >= max) { 26330725Syokota dxpos = max; 26430725Syokota dxdir = -1; 26530725Syokota } 26630725Syokota 26730725Syokota if (scp->ysize <= DAEMON_MAX_HEIGHT) { 26830725Syokota min = scp->ysize - DAEMON_MAX_HEIGHT - 10; 26930725Syokota max = 10; 27025968Syokota } else { 27130725Syokota min = 0; 27230725Syokota max = scp->ysize - DAEMON_MAX_HEIGHT; 27325968Syokota } 27430725Syokota if (dypos <= min) { 27530725Syokota dypos = min; 27630725Syokota dydir = 1; 27730725Syokota } else if (dypos >= max) { 27830725Syokota dypos = max; 27930725Syokota dydir = -1; 28030725Syokota } 28130725Syokota 28225968Syokota moved_daemon = -1; 28325968Syokota dxpos += dxdir; dypos += dydir; 28430725Syokota 28530725Syokota /* clip the picture */ 28630725Syokota xoff = 0; 28730725Syokota xlen = DAEMON_MAX_WIDTH; 28830725Syokota if (dxpos + xlen <= 0) 28930725Syokota xlen = 0; 29030725Syokota else if (dxpos < 0) 29130725Syokota xoff = -dxpos; 29230725Syokota if (dxpos >= scp->xsize) 29330725Syokota xlen = 0; 29430725Syokota else if (dxpos + xlen > scp->xsize) 29530725Syokota xlen = scp->xsize - dxpos; 29630725Syokota yoff = 0; 29730725Syokota ylen = DAEMON_MAX_HEIGHT; 29830725Syokota if (dypos + ylen <= 0) 29930725Syokota ylen = 0; 30030725Syokota else if (dypos < 0) 30130725Syokota yoff = -dypos; 30230725Syokota if (dypos >= scp->ysize) 30330725Syokota ylen = 0; 30430725Syokota else if (dypos + ylen > scp->ysize) 30530725Syokota ylen = scp->ysize - dypos; 30625968Syokota } 30725968Syokota 30830725Syokota if (scp->xsize <= messagelen) { 30930725Syokota min = scp->xsize - messagelen - 10; 31030725Syokota max = 10; 31125968Syokota } else { 31230725Syokota min = 0; 31330725Syokota max = scp->xsize - messagelen; 31425968Syokota } 31530725Syokota if (txpos <= min) { 31630725Syokota txpos = min; 31730725Syokota txdir = 1; 31830725Syokota } else if (txpos >= max) { 31930725Syokota txpos = max; 32030725Syokota txdir = -1; 32125968Syokota } 32230725Syokota if (typos <= 0) { 32330725Syokota typos = 0; 32430725Syokota tydir = 1; 32530725Syokota } else if (typos >= scp->ysize - 1) { 32630725Syokota typos = scp->ysize - 1; 32730725Syokota tydir = -1; 32830725Syokota } 32925968Syokota txpos += txdir; typos += tydir; 33025968Syokota 33130725Syokota toff = 0; 33230725Syokota tlen = messagelen; 33330725Syokota if (txpos + tlen <= 0) 33430725Syokota tlen = 0; 33530725Syokota else if (txpos < 0) 33630725Syokota toff = -txpos; 33730725Syokota if (txpos >= scp->xsize) 33830725Syokota tlen = 0; 33930725Syokota else if (txpos + tlen > scp->xsize) 34030725Syokota tlen = scp->xsize - txpos; 34130725Syokota 34248104Syokota draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); 34372797Snyan draw_string(sc, txpos, typos, toff, message, tlen); 344146238Snyan } else 34542504Syokota blanked = 0; 346146238Snyan 34742504Syokota return 0; 34825968Syokota} 34925968Syokota 35025968Syokotastatic int 35142504Syokotadaemon_init(video_adapter_t *adp) 35225968Syokota{ 35327427Syokota messagelen = strlen(hostname) + 3 + strlen(ostype) + 1 + 35427427Syokota strlen(osrelease); 355111119Simp message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK); 35627427Syokota sprintf(message, "%s - %s %s", hostname, ostype, osrelease); 35742504Syokota blanked = 0; 358146238Snyan switch (adp->va_mode) { 359146238Snyan case M_PC98_80x25: 360146238Snyan case M_PC98_80x30: 361146238Snyan attr_mask = ~FG_UNDERLINE; 362146238Snyan break; 363146238Snyan default: 364146238Snyan attr_mask = ~0; 365146238Snyan break; 366146238Snyan } 367146238Snyan 36842504Syokota return 0; 36925968Syokota} 37025968Syokota 37125968Syokotastatic int 37242504Syokotadaemon_term(video_adapter_t *adp) 37325968Syokota{ 37442504Syokota free(message, M_DEVBUF); 37542504Syokota return 0; 37625968Syokota} 37725968Syokota 37842504Syokotastatic scrn_saver_t daemon_module = { 37942504Syokota "daemon_saver", daemon_init, daemon_term, daemon_saver, NULL, 38042504Syokota}; 38142504Syokota 38242504SyokotaSAVER_MODULE(daemon_saver, daemon_module); 383