summaryrefslogtreecommitdiffstats
path: root/sys/modules/syscons
diff options
context:
space:
mode:
authoryokota <yokota@FreeBSD.org>1997-10-26 07:35:18 +0000
committeryokota <yokota@FreeBSD.org>1997-10-26 07:35:18 +0000
commit72e6a767474540e8fe55e418eb271c467e8f8144 (patch)
treeabb2820147667d27196458de8bf880d428b0f5d4 /sys/modules/syscons
parent0689fa1ceb9804e257bcefc12b99b194cb4179b8 (diff)
downloadFreeBSD-src-72e6a767474540e8fe55e418eb271c467e8f8144.zip
FreeBSD-src-72e6a767474540e8fe55e418eb271c467e8f8144.tar.gz
- The daemon might go off the screen and crashed the system if the
screen size was changed while the screen saver was inactive. Adjust the positions of the daemon and the text and clip them accordingly each time. - Don't call set_border() too often. Some video chip may produce flicker. Pointed out by tony@dell.com - Don't fill the entire screen with blank char every time the saver is called. Blank only the part of the screen where the daemon and the text was previously printed.
Diffstat (limited to 'sys/modules/syscons')
-rw-r--r--sys/modules/syscons/daemon/daemon_saver.c183
1 files changed, 148 insertions, 35 deletions
diff --git a/sys/modules/syscons/daemon/daemon_saver.c b/sys/modules/syscons/daemon/daemon_saver.c
index 3325ad3..ca00b46 100644
--- a/sys/modules/syscons/daemon/daemon_saver.c
+++ b/sys/modules/syscons/daemon/daemon_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: daemon_saver.c,v 1.5 1997/06/24 12:43:18 yokota Exp $
+ * $Id: daemon_saver.c,v 1.6 1997/07/15 14:49:16 yokota Exp $
*/
#include <sys/param.h>
@@ -43,7 +43,7 @@
#include <saver.h>
#define CONSOLE_VECT(x, y) \
- *((u_short*)(Crtat + (y)*cur_console->xsize + (x)))
+ ((u_short*)(Crtat + (y)*cur_console->xsize + (x)))
#define DAEMON_MAX_WIDTH 32
#define DAEMON_MAX_HEIGHT 19
@@ -121,14 +121,35 @@ xflip_symbol(char symbol)
}
static void
-draw_daemon(int xpos, int ypos, int dxdir)
+clear_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
+ int xlen, int ylen)
+{
+ int y;
+
+ if (xlen <= 0)
+ return;
+ for (y = yoff; y < ylen; y++)
+ fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
+ CONSOLE_VECT(xpos + xoff, ypos + y), xlen - xoff);
+}
+
+static void
+draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
+ int xlen, int ylen)
{
int x, y;
+ int px;
int attr;
- for (y = 0; daemon_pic[y] != NULL; y++)
- for (x = 0; daemon_pic[y][x] != '\0'; x++) {
- switch (daemon_attr[y][x]) {
+ for (y = yoff; y < ylen; y++) {
+ if (dxdir < 0)
+ px = xoff;
+ else
+ px = DAEMON_MAX_WIDTH - xlen;
+ if (px >= strlen(daemon_pic[y]))
+ continue;
+ for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) {
+ switch (daemon_attr[y][px]) {
case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break;
case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break;
case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break;
@@ -137,22 +158,32 @@ draw_daemon(int xpos, int ypos, int dxdir)
default: attr = (FG_WHITE|BG_BLACK)<<8; break;
}
if (dxdir < 0) { /* Moving left */
- CONSOLE_VECT(xpos + x, ypos + y) =
- scr_map[daemon_pic[y][x]]|attr;
+ *CONSOLE_VECT(xpos + x, ypos + y) =
+ scr_map[daemon_pic[y][px]]|attr;
} else { /* Moving right */
- CONSOLE_VECT(xpos + DAEMON_MAX_WIDTH - x - 1, ypos + y) =
- scr_map[xflip_symbol(daemon_pic[y][x])]|attr;
+ *CONSOLE_VECT(xpos + DAEMON_MAX_WIDTH - px - 1, ypos + y) =
+ scr_map[xflip_symbol(daemon_pic[y][px])]|attr;
}
}
+ }
+}
+
+static void
+clear_string(int xpos, int ypos, int xoff, char *s, int len)
+{
+ if (len <= 0)
+ return;
+ fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
+ CONSOLE_VECT(xpos + xoff, ypos), len - xoff);
}
static void
-draw_string(int xpos, int ypos, char *s, int len)
+draw_string(int xpos, int ypos, int xoff, char *s, int len)
{
int x;
- for (x = 0; x < len; x++)
- CONSOLE_VECT(xpos + x, ypos) =
+ for (x = xoff; x < len; x++)
+ *CONSOLE_VECT(xpos + x, ypos) =
scr_map[s[x]]|(FG_LIGHTGREEN|BG_BLACK)<<8;
}
@@ -164,49 +195,131 @@ daemon_saver(int blank)
static int dxpos = 0, dypos = 0;
static int dxdir = 1, dydir = 1;
static int moved_daemon = 0;
+ static int xoff, yoff, toff;
+ static int xlen, ylen, tlen;
scr_stat *scp = cur_console;
+ int min, max;
if (blank) {
+ if (scrn_blanked == 0) {
+ /* clear the screen and set the border color */
+ fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
+ Crtat, scp->xsize * scp->ysize);
+ set_border(0);
+ xlen = ylen = tlen = 0;
+ }
if (scrn_blanked++ < 2)
return;
- fillw((FG_LIGHTGREY|BG_BLACK)<<8|scr_map[0x20], Crtat,
- scp->xsize * scp->ysize);
- set_border(0);
scrn_blanked = 1;
+ clear_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
+ clear_string(txpos, typos, toff, (char *)message, tlen);
+
if (++moved_daemon) {
- if (dxdir > 0) {
- if (dxpos == scp->xsize - DAEMON_MAX_WIDTH)
- dxdir = -1;
+ /*
+ * The daemon picture may be off the screen, if
+ * screen size is chagened while the screen
+ * saver is inactive. Make sure the origin of
+ * the picture is between min and max.
+ */
+ if (scp->xsize <= DAEMON_MAX_WIDTH) {
+ /*
+ * If the screen width is too narrow, we
+ * allow part of the picture go off
+ * the screen so that the daemon won't
+ * flip too often.
+ */
+ min = scp->xsize - DAEMON_MAX_WIDTH - 10;
+ max = 10;
} else {
- if (dxpos == 0) dxdir = 1;
+ min = 0;
+ max = scp->xsize - DAEMON_MAX_WIDTH;
+ }
+ if (dxpos <= min) {
+ dxpos = min;
+ dxdir = 1;
+ } else if (dxpos >= max) {
+ dxpos = max;
+ dxdir = -1;
}
- if (dydir > 0) {
- if (dypos == scp->ysize - DAEMON_MAX_HEIGHT)
- dydir = -1;
+
+ if (scp->ysize <= DAEMON_MAX_HEIGHT) {
+ min = scp->ysize - DAEMON_MAX_HEIGHT - 10;
+ max = 10;
} else {
- if (dypos == 0) dydir = 1;
+ min = 0;
+ max = scp->ysize - DAEMON_MAX_HEIGHT;
+ }
+ if (dypos <= min) {
+ dypos = min;
+ dydir = 1;
+ } else if (dypos >= max) {
+ dypos = max;
+ dydir = -1;
}
+
moved_daemon = -1;
dxpos += dxdir; dypos += dydir;
+
+ /* clip the picture */
+ xoff = 0;
+ xlen = DAEMON_MAX_WIDTH;
+ if (dxpos + xlen <= 0)
+ xlen = 0;
+ else if (dxpos < 0)
+ xoff = -dxpos;
+ if (dxpos >= scp->xsize)
+ xlen = 0;
+ else if (dxpos + xlen > scp->xsize)
+ xlen = scp->xsize - dxpos;
+ yoff = 0;
+ ylen = DAEMON_MAX_HEIGHT;
+ if (dypos + ylen <= 0)
+ ylen = 0;
+ else if (dypos < 0)
+ yoff = -dypos;
+ if (dypos >= scp->ysize)
+ ylen = 0;
+ else if (dypos + ylen > scp->ysize)
+ ylen = scp->ysize - dypos;
}
- if (txdir > 0) {
- if (txpos == scp->xsize - messagelen)
- txdir = -1;
+ if (scp->xsize <= messagelen) {
+ min = scp->xsize - messagelen - 10;
+ max = 10;
} else {
- if (txpos == 0) txdir = 1;
+ min = 0;
+ max = scp->xsize - messagelen;
}
- if (tydir > 0) {
- if (typos == scp->ysize - 1)
- tydir = -1;
- } else {
- if (typos == 0) tydir = 1;
+ if (txpos <= min) {
+ txpos = min;
+ txdir = 1;
+ } else if (txpos >= max) {
+ txpos = max;
+ txdir = -1;
+ }
+ if (typos <= 0) {
+ typos = 0;
+ tydir = 1;
+ } else if (typos >= scp->ysize - 1) {
+ typos = scp->ysize - 1;
+ tydir = -1;
}
txpos += txdir; typos += tydir;
- draw_daemon(dxpos, dypos, dxdir);
- draw_string(txpos, typos, (char *)message, messagelen);
+ toff = 0;
+ tlen = messagelen;
+ if (txpos + tlen <= 0)
+ tlen = 0;
+ else if (txpos < 0)
+ toff = -txpos;
+ if (txpos >= scp->xsize)
+ tlen = 0;
+ else if (txpos + tlen > scp->xsize)
+ tlen = scp->xsize - txpos;
+
+ draw_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
+ draw_string(txpos, typos, toff, (char *)message, tlen);
} else {
if (scrn_blanked > 0) {
set_border(scp->border);
OpenPOWER on IntegriCloud