From 02f2e93b60c2b91feac8f45c4c889a5a8e40d8a2 Mon Sep 17 00:00:00 2001 From: Kazutaka YOKOTA Date: Sun, 26 Oct 1997 07:35:18 +0000 Subject: [PATCH] - 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. --- lkm/syscons/daemon/daemon_saver.c | 183 +++++++++++++++++----- sys/dev/syscons/daemon/daemon_saver.c | 183 +++++++++++++++++----- sys/modules/syscons/daemon/daemon_saver.c | 183 +++++++++++++++++----- 3 files changed, 444 insertions(+), 105 deletions(-) diff --git a/lkm/syscons/daemon/daemon_saver.c b/lkm/syscons/daemon/daemon_saver.c index 3325ad3a011..ca00b46c472 100644 --- a/lkm/syscons/daemon/daemon_saver.c +++ b/lkm/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 @@ -43,7 +43,7 @@ #include #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 -draw_string(int xpos, int ypos, char *s, int len) +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, 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 (dydir > 0) { - if (dypos == scp->ysize - DAEMON_MAX_HEIGHT) - dydir = -1; + if (dxpos <= min) { + dxpos = min; + dxdir = 1; + } else if (dxpos >= max) { + dxpos = max; + dxdir = -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); diff --git a/sys/dev/syscons/daemon/daemon_saver.c b/sys/dev/syscons/daemon/daemon_saver.c index 3325ad3a011..ca00b46c472 100644 --- a/sys/dev/syscons/daemon/daemon_saver.c +++ b/sys/dev/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 @@ -43,7 +43,7 @@ #include #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 -draw_string(int xpos, int ypos, char *s, int len) +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, 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 (dydir > 0) { - if (dypos == scp->ysize - DAEMON_MAX_HEIGHT) - dydir = -1; + if (dxpos <= min) { + dxpos = min; + dxdir = 1; + } else if (dxpos >= max) { + dxpos = max; + dxdir = -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); diff --git a/sys/modules/syscons/daemon/daemon_saver.c b/sys/modules/syscons/daemon/daemon_saver.c index 3325ad3a011..ca00b46c472 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 @@ -43,7 +43,7 @@ #include #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 -draw_string(int xpos, int ypos, char *s, int len) +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, 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 (dydir > 0) { - if (dypos == scp->ysize - DAEMON_MAX_HEIGHT) - dydir = -1; + if (dxpos <= min) { + dxpos = min; + dxdir = 1; + } else if (dxpos >= max) { + dxpos = max; + dxdir = -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);