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$ 2925968Syokota */ 3025968Syokota 3125968Syokota#include <sys/param.h> 3225968Syokota#include <sys/systm.h> 3340885Speter#include <sys/module.h> 3427427Syokota#include <sys/malloc.h> 35193066Sjamie#include <sys/jail.h> 3626893Syokota#include <sys/kernel.h> 3726893Syokota#include <sys/sysctl.h> 3848104Syokota#include <sys/consio.h> 3948104Syokota#include <sys/fbio.h> 4025968Syokota 4132571Sbde#include <machine/pc/display.h> 4225968Syokota 4348104Syokota#include <dev/fb/fbreg.h> 4448104Syokota#include <dev/fb/splashreg.h> 4548104Syokota#include <dev/syscons/syscons.h> 4625968Syokota 4725968Syokota#define DAEMON_MAX_WIDTH 32 4825968Syokota#define DAEMON_MAX_HEIGHT 19 4925968Syokota 5072797Snyanstatic u_char *message; 5127427Syokotastatic int messagelen; 5242504Syokotastatic int blanked; 53146238Snyanstatic int attr_mask; 5427427Syokota 55146238Snyan#define ATTR(attr) (((attr) & attr_mask) << 8) 56146238Snyan 5726081Syokota/* Who is the author of this ASCII pic? */ 5826081Syokota 5972797Snyanstatic u_char *daemon_pic[] = { 6025968Syokota " , ,", 6125968Syokota " /( )`", 6225968Syokota " \\ \\___ / |", 6325968Syokota " /- _ `-/ '", 6425968Syokota " (/\\/ \\ \\ /\\", 6525968Syokota " / / | ` \\", 6625968Syokota " O O ) / |", 6725968Syokota " `-^--'`< '", 6825968Syokota " (_.) _ ) /", 6925968Syokota " `.___/` /", 7025968Syokota " `-----' /", 7125968Syokota "<----. __ / __ \\", 7225968Syokota "<----|====O)))==) \\) /====", 7325968Syokota "<----' `--' `.__,' \\", 7425968Syokota " | |", 7525968Syokota " \\ / /\\", 7625968Syokota " ______( (_ / \\______/", 7725968Syokota " ,' ,-----' |", 7825968Syokota " `--{__________)", 7925968Syokota NULL 8025968Syokota}; 8125968Syokota 8272797Snyanstatic u_char *daemon_attr[] = { 8325968Syokota " R R", 8425968Syokota " RR RR", 8525968Syokota " R RRRR R R", 8625968Syokota " RR W RRR R", 8725968Syokota " RWWW W R RR", 8825968Syokota " W W W R R", 8925968Syokota " B B W R R", 9025968Syokota " WWWWWWRR R", 9125968Syokota " RRRR R R R", 9225968Syokota " RRRRRRR R", 9325968Syokota " RRRRRRR R", 9425968Syokota "YYYYYY RR R RR R", 9525968Syokota "YYYYYYYYYYRRRRYYR RR RYYYY", 9625968Syokota "YYYYYY RRRR RRRRRR R", 9725968Syokota " R R", 9825968Syokota " R R RR", 9925968Syokota " CCCCCCR RR R RRRRRRRR", 10025968Syokota " CC CCCCCCC C", 10125968Syokota " CCCCCCCCCCCCCCC", 10225968Syokota NULL 10325968Syokota}; 10425968Syokota 10526081Syokota/* 10626081Syokota * Reverse a graphics character, or return unaltered if no mirror; 10726081Syokota * should do alphanumerics too, but I'm too lazy. <cshenton@it.hq.nasa.gov> 10826081Syokota */ 10925968Syokota 11072797Snyanstatic u_char 11172797Snyanxflip_symbol(u_char symbol) 11226081Syokota{ 11372797Snyan static const u_char lchars[] = "`'(){}[]\\/<>"; 11472797Snyan static const u_char rchars[] = "'`)(}{][/\\><"; 11526081Syokota int pos; 11626081Syokota 11726081Syokota for (pos = 0; lchars[pos] != '\0'; pos++) 11826081Syokota if (lchars[pos] == symbol) 11926081Syokota return rchars[pos]; 12026081Syokota 12126081Syokota return symbol; 12226081Syokota} 12326081Syokota 12425968Syokotastatic void 12548104Syokotaclear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff, 12630725Syokota int xlen, int ylen) 12725968Syokota{ 12830725Syokota int y; 12930725Syokota 13030725Syokota if (xlen <= 0) 13130725Syokota return; 13248104Syokota for (y = yoff; y < ylen; y++) { 13348104Syokota sc_vtb_erase(&sc->cur_scp->scr, 13448104Syokota (ypos + y)*sc->cur_scp->xsize + xpos + xoff, 13548104Syokota xlen - xoff, 136146238Snyan sc->scr_map[0x20], ATTR(FG_LIGHTGREY | BG_BLACK)); 13748104Syokota } 13830725Syokota} 13930725Syokota 14030725Syokotastatic void 14148104Syokotadraw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff, 14230725Syokota int xlen, int ylen) 14330725Syokota{ 14425968Syokota int x, y; 14530725Syokota int px; 14625968Syokota int attr; 14725968Syokota 14830725Syokota for (y = yoff; y < ylen; y++) { 14930725Syokota if (dxdir < 0) 15030725Syokota px = xoff; 15130725Syokota else 15230725Syokota px = DAEMON_MAX_WIDTH - xlen; 15330725Syokota if (px >= strlen(daemon_pic[y])) 15430725Syokota continue; 15530725Syokota for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) { 15630725Syokota switch (daemon_attr[y][px]) { 157146238Snyan case 'R': attr = FG_LIGHTRED | BG_BLACK; break; 158146238Snyan case 'Y': attr = FG_YELLOW | BG_BLACK; break; 159146238Snyan case 'B': attr = FG_LIGHTBLUE | BG_BLACK; break; 160146238Snyan case 'W': attr = FG_LIGHTGREY | BG_BLACK; break; 161146238Snyan case 'C': attr = FG_CYAN | BG_BLACK; break; 162146238Snyan default: attr = FG_WHITE | BG_BLACK; break; 16325968Syokota } 16426081Syokota if (dxdir < 0) { /* Moving left */ 16548104Syokota sc_vtb_putc(&sc->cur_scp->scr, 16648104Syokota (ypos + y)*sc->cur_scp->xsize 16748104Syokota + xpos + x, 16848104Syokota sc->scr_map[daemon_pic[y][px]], 169146238Snyan ATTR(attr)); 17026081Syokota } else { /* Moving right */ 17148104Syokota sc_vtb_putc(&sc->cur_scp->scr, 17248104Syokota (ypos + y)*sc->cur_scp->xsize 17348104Syokota + xpos + DAEMON_MAX_WIDTH 17448104Syokota - px - 1, 17548104Syokota sc->scr_map[xflip_symbol(daemon_pic[y][px])], 176146238Snyan ATTR(attr)); 17726081Syokota } 17825968Syokota } 17930725Syokota } 18025968Syokota} 18125968Syokota 18225968Syokotastatic void 18348104Syokotaclear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len) 18425968Syokota{ 18530725Syokota if (len <= 0) 18630725Syokota return; 18748104Syokota sc_vtb_erase(&sc->cur_scp->scr, 18848104Syokota ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff, 189146238Snyan sc->scr_map[0x20], ATTR(FG_LIGHTGREY | BG_BLACK)); 19030725Syokota} 19130725Syokota 19230725Syokotastatic void 19372797Snyandraw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, u_char *s, int len) 19430725Syokota{ 19525968Syokota int x; 19625968Syokota 197146238Snyan for (x = xoff; x < len; x++) 19848104Syokota sc_vtb_putc(&sc->cur_scp->scr, 19948104Syokota ypos*sc->cur_scp->xsize + xpos + x, 200146238Snyan sc->scr_map[s[x]], ATTR(FG_LIGHTGREEN | BG_BLACK)); 20125968Syokota} 20225968Syokota 20342504Syokotastatic int 20442504Syokotadaemon_saver(video_adapter_t *adp, int blank) 20525968Syokota{ 20626081Syokota static int txpos = 10, typos = 10; 20726081Syokota static int txdir = -1, tydir = -1; 20825968Syokota static int dxpos = 0, dypos = 0; 20925968Syokota static int dxdir = 1, dydir = 1; 21025968Syokota static int moved_daemon = 0; 21130725Syokota static int xoff, yoff, toff; 21230725Syokota static int xlen, ylen, tlen; 21348104Syokota sc_softc_t *sc; 21448104Syokota scr_stat *scp; 21530725Syokota int min, max; 21625968Syokota 21748104Syokota sc = sc_find_softc(adp, NULL); 21848104Syokota if (sc == NULL) 21948104Syokota return EAGAIN; 22048104Syokota scp = sc->cur_scp; 22148104Syokota 22225968Syokota if (blank) { 22343673Sdes if (adp->va_info.vi_flags & V_INFO_GRAPHICS) 22442749Syokota return EAGAIN; 22542504Syokota if (blanked == 0) { 22630725Syokota /* clear the screen and set the border color */ 22748104Syokota sc_vtb_clear(&scp->scr, sc->scr_map[0x20], 228146238Snyan ATTR(FG_LIGHTGREY | BG_BLACK)); 229174985Swkoszek vidd_set_hw_cursor(adp, -1, -1); 23056043Syokota sc_set_border(scp, 0); 23130725Syokota xlen = ylen = tlen = 0; 23230725Syokota } 23342504Syokota if (blanked++ < 2) 23442504Syokota return 0; 23542504Syokota blanked = 1; 23625968Syokota 23748104Syokota clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); 23872797Snyan clear_string(sc, txpos, typos, toff, message, tlen); 23930725Syokota 24025968Syokota if (++moved_daemon) { 24130725Syokota /* 24230725Syokota * The daemon picture may be off the screen, if 24330725Syokota * screen size is chagened while the screen 24430725Syokota * saver is inactive. Make sure the origin of 24530725Syokota * the picture is between min and max. 24630725Syokota */ 24730725Syokota if (scp->xsize <= DAEMON_MAX_WIDTH) { 24830725Syokota /* 24930725Syokota * If the screen width is too narrow, we 25030725Syokota * allow part of the picture go off 25130725Syokota * the screen so that the daemon won't 25230725Syokota * flip too often. 25330725Syokota */ 25430725Syokota min = scp->xsize - DAEMON_MAX_WIDTH - 10; 25530725Syokota max = 10; 25625968Syokota } else { 25730725Syokota min = 0; 25830725Syokota max = scp->xsize - DAEMON_MAX_WIDTH; 25925968Syokota } 26030725Syokota if (dxpos <= min) { 26130725Syokota dxpos = min; 26230725Syokota dxdir = 1; 26330725Syokota } else if (dxpos >= max) { 26430725Syokota dxpos = max; 26530725Syokota dxdir = -1; 26630725Syokota } 26730725Syokota 26830725Syokota if (scp->ysize <= DAEMON_MAX_HEIGHT) { 26930725Syokota min = scp->ysize - DAEMON_MAX_HEIGHT - 10; 27030725Syokota max = 10; 27125968Syokota } else { 27230725Syokota min = 0; 27330725Syokota max = scp->ysize - DAEMON_MAX_HEIGHT; 27425968Syokota } 27530725Syokota if (dypos <= min) { 27630725Syokota dypos = min; 27730725Syokota dydir = 1; 27830725Syokota } else if (dypos >= max) { 27930725Syokota dypos = max; 28030725Syokota dydir = -1; 28130725Syokota } 28230725Syokota 28325968Syokota moved_daemon = -1; 28425968Syokota dxpos += dxdir; dypos += dydir; 28530725Syokota 28630725Syokota /* clip the picture */ 28730725Syokota xoff = 0; 28830725Syokota xlen = DAEMON_MAX_WIDTH; 28930725Syokota if (dxpos + xlen <= 0) 29030725Syokota xlen = 0; 29130725Syokota else if (dxpos < 0) 29230725Syokota xoff = -dxpos; 29330725Syokota if (dxpos >= scp->xsize) 29430725Syokota xlen = 0; 29530725Syokota else if (dxpos + xlen > scp->xsize) 29630725Syokota xlen = scp->xsize - dxpos; 29730725Syokota yoff = 0; 29830725Syokota ylen = DAEMON_MAX_HEIGHT; 29930725Syokota if (dypos + ylen <= 0) 30030725Syokota ylen = 0; 30130725Syokota else if (dypos < 0) 30230725Syokota yoff = -dypos; 30330725Syokota if (dypos >= scp->ysize) 30430725Syokota ylen = 0; 30530725Syokota else if (dypos + ylen > scp->ysize) 30630725Syokota ylen = scp->ysize - dypos; 30725968Syokota } 30825968Syokota 30930725Syokota if (scp->xsize <= messagelen) { 31030725Syokota min = scp->xsize - messagelen - 10; 31130725Syokota max = 10; 31225968Syokota } else { 31330725Syokota min = 0; 31430725Syokota max = scp->xsize - messagelen; 31525968Syokota } 31630725Syokota if (txpos <= min) { 31730725Syokota txpos = min; 31830725Syokota txdir = 1; 31930725Syokota } else if (txpos >= max) { 32030725Syokota txpos = max; 32130725Syokota txdir = -1; 32225968Syokota } 32330725Syokota if (typos <= 0) { 32430725Syokota typos = 0; 32530725Syokota tydir = 1; 32630725Syokota } else if (typos >= scp->ysize - 1) { 32730725Syokota typos = scp->ysize - 1; 32830725Syokota tydir = -1; 32930725Syokota } 33025968Syokota txpos += txdir; typos += tydir; 33125968Syokota 33230725Syokota toff = 0; 33330725Syokota tlen = messagelen; 33430725Syokota if (txpos + tlen <= 0) 33530725Syokota tlen = 0; 33630725Syokota else if (txpos < 0) 33730725Syokota toff = -txpos; 33830725Syokota if (txpos >= scp->xsize) 33930725Syokota tlen = 0; 34030725Syokota else if (txpos + tlen > scp->xsize) 34130725Syokota tlen = scp->xsize - txpos; 34230725Syokota 34348104Syokota draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); 34472797Snyan draw_string(sc, txpos, typos, toff, message, tlen); 345146238Snyan } else 34642504Syokota blanked = 0; 347146238Snyan 34842504Syokota return 0; 34925968Syokota} 35025968Syokota 35125968Syokotastatic int 35242504Syokotadaemon_init(video_adapter_t *adp) 35325968Syokota{ 354197062Sjhb size_t hostlen; 355180291Srwatson 356193066Sjamie mtx_lock(&prison0.pr_mtx); 357197062Sjhb for (;;) { 358197062Sjhb hostlen = strlen(prison0.pr_hostname); 359197062Sjhb mtx_unlock(&prison0.pr_mtx); 360197062Sjhb 361197062Sjhb messagelen = hostlen + 3 + strlen(ostype) + 1 + 362197062Sjhb strlen(osrelease); 363197062Sjhb message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK); 364197062Sjhb mtx_lock(&prison0.pr_mtx); 365197062Sjhb if (hostlen < strlen(prison0.pr_hostname)) { 366197062Sjhb free(message, M_DEVBUF); 367197062Sjhb continue; 368197062Sjhb } 369197062Sjhb break; 370197062Sjhb } 371194118Sjamie sprintf(message, "%s - %s %s", prison0.pr_hostname, ostype, osrelease); 372193066Sjamie mtx_unlock(&prison0.pr_mtx); 37342504Syokota blanked = 0; 374146238Snyan switch (adp->va_mode) { 375146238Snyan case M_PC98_80x25: 376146238Snyan case M_PC98_80x30: 377146238Snyan attr_mask = ~FG_UNDERLINE; 378146238Snyan break; 379146238Snyan default: 380146238Snyan attr_mask = ~0; 381146238Snyan break; 382146238Snyan } 383146238Snyan 38442504Syokota return 0; 38525968Syokota} 38625968Syokota 38725968Syokotastatic int 38842504Syokotadaemon_term(video_adapter_t *adp) 38925968Syokota{ 39042504Syokota free(message, M_DEVBUF); 39142504Syokota return 0; 39225968Syokota} 39325968Syokota 39442504Syokotastatic scrn_saver_t daemon_module = { 39542504Syokota "daemon_saver", daemon_init, daemon_term, daemon_saver, NULL, 39642504Syokota}; 39742504Syokota 39842504SyokotaSAVER_MODULE(daemon_saver, daemon_module); 399