home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software, Co. */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / Freely Available<tm> Software. */
- /* \ 1011 / */
- /* ------ */
- /* */
- /* (C) Copyright 1987-96, Bit Bucket Software Co. */
- /* */
- /* */
- /* */
- /* Box Drawing subroutines for BinkleyTerm */
- /* */
- /* */
- /* For complete details of the licensing restrictions, please refer */
- /* to the License agreement, which is published in its entirety in */
- /* the MAKEFILE and BT.C, and also contained in the file LICENSE.260. */
- /* */
- /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
- /* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
- /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
- /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
- /* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
- /* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
- /* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
- /* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
- /* */
- /* */
- /* You can contact Bit Bucket Software Co. at any one of the following */
- /* addresses: */
- /* */
- /* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
- /* P.O. Box 460398 AlterNet 7:42/1491 */
- /* Aurora, CO 80046 BBS-Net 86:2030/1 */
- /* Internet f491.n343.z1.fidonet.org */
- /* */
- /* Please feel free to contact us at any time to share your comments about */
- /* our software and/or licensing policies. */
- /* */
- /* */
- /* This module is derived from code developed by Augie Hansen in his */
- /* book "Proficient C" published by Microsoft Press. Mr. Hansen was */
- /* kind enough to give us verbal permission to use his routines, and */
- /* Bob, Vince and Alan (and all our full screen users) are grateful. */
- /* If you decide to use this code in some package you are doing, give */
- /* some thought to going out and buying the book. He deserves that. */
- /* */
- /*--------------------------------------------------------------------------*/
-
- /* Include this file before any other includes or defines! */
-
- #include "includes.h"
-
- #include "box.h"
- #include "video.h"
-
- BUFFER Sbuf; /* control information */
- CELLP Scrnbuf; /* screen buffer array */
-
- extern int cursor_col;
- extern int cursor_row;
-
- #define WHITEBLANK (7 << 8) | ' '
-
- static BOXTYPE box[] =
- {
- '+', '+', '+', '+', '-', '-', '|', '|',
- ULC11, URC11, LLC11, LRC11, HBAR1, HBAR1, VBAR1, VBAR1,
- ULC22, URC22, LLC22, LRC22, HBAR2, HBAR2, VBAR2, VBAR2,
- ULC12, URC12, LLC12, LRC12, HBAR1, HBAR1, VBAR2, VBAR2,
- ULC21, URC21, LLC21, LRC21, HBAR2, HBAR2, VBAR1, VBAR1,
- BLOCK, BLOCK, BLOCK, BLOCK, HBART, HBARB, BLOCK, BLOCK
- };
-
- void
- sb_box (REGIONP win, short type, short attr)
- {
- register short r;
- short x;
- short maxr, maxc;
- BOXTYPE *boxp;
-
- boxp = &box[type];
- maxc = win->c1 - win->c0;
- maxr = win->r1 - win->r0;
- x = maxc - 1;
-
- /* draw top row */
- sb_move (win, 0, 0);
- sb_wca (win, boxp->ul, attr, 1);
- sb_move (win, 0, 1);
- sb_wca (win, boxp->tbar, attr, x);
- sb_move (win, 0, maxc);
- sb_wca (win, boxp->ur, attr, 1);
-
- /* draw left and right sides */
- for (r = 1; r < maxr; r++)
- {
- sb_move (win, r, 0);
- sb_wca (win, boxp->lbar, attr, 1);
- sb_move (win, r, maxc);
- sb_wca (win, boxp->rbar, attr, 1);
- }
-
- /* draw bottom row */
- sb_move (win, maxr, 0);
- sb_wca (win, boxp->ll, attr, 1);
- sb_move (win, maxr, 1);
- sb_wca (win, boxp->bbar, attr, x);
- sb_move (win, maxr, maxc);
- sb_wca (win, boxp->lr, attr, 1);
- }
-
- void
- sb_fill (REGIONP win, short ch, short attr)
- {
- register short i, j;
- unsigned short ca;
-
- ca = ((unsigned short) attr << 8) | (unsigned short) ch;
-
- for (i = win->sr0; i <= win->sr1; i++)
- {
- for (j = win->sc0; j <= win->sc1; j++)
- {
- (Scrnbuf + i * SB_COLS + j)->cap = ca;
- }
- if (win->sc0 < Sbuf.lcol[i])
- {
- Sbuf.lcol[i] = win->sc0;
- }
- if (win->sc1 > Sbuf.rcol[i])
- {
- Sbuf.rcol[i] = win->sc1;
- }
- }
-
- Sbuf.flags |= SB_DELTA;
- return;
- }
-
- void
- sb_fillc (REGIONP win, short ch)
- {
- register short i, j;
-
- for (i = win->sr0; i <= win->sr1; i++)
- {
- for (j = win->sc0; j <= win->sc1; j++)
- {
- (Scrnbuf + i * SB_COLS + j)->b.ch = (unsigned char) ch;
- }
- if (win->sc0 < Sbuf.lcol[i])
- {
- Sbuf.lcol[i] = win->sc0;
- }
- if (win->sc1 > Sbuf.rcol[i])
- {
- Sbuf.rcol[i] = win->sc1;
- }
- }
-
- Sbuf.flags |= SB_DELTA;
- return;
- }
-
- void
- sb_filla (REGIONP win, short attr)
- {
- register short i, j;
-
- for (i = win->sr0; i <= win->sr1; i++)
- {
- for (j = win->sc0; j <= win->sc1; j++)
- {
- (Scrnbuf + i * SB_COLS + j)->b.attr = (unsigned char) attr;
- }
- if (win->sc0 < Sbuf.lcol[i])
- {
- Sbuf.lcol[i] = win->sc0;
- }
- if (win->sc1 > Sbuf.rcol[i])
- {
- Sbuf.rcol[i] = win->sc1;
- }
- }
-
- Sbuf.flags |= SB_DELTA;
- return;
- }
-
- void
- sb_init ()
- {
- short i, j;
- CELLP c;
- char q[20];
-
- Scrnbuf = (CELLP) calloc ((unsigned short) SB_ROWS * (unsigned short) SB_COLS, sizeof (CELL));
- Sbuf.bp = (CELLP) Scrnbuf;
-
- Sbuf.row = Sbuf.col = 0;
- Sbuf.lcol = (short *) calloc ((unsigned short) SB_COLS, sizeof (short));
- Sbuf.rcol = (short *) calloc ((unsigned short) SB_ROWS, sizeof (short));
-
- (void) sprintf (q, "-%d.%ds", SB_COLS - 16, SB_COLS - 16);
- (void) strcpy (&stat_str[19], q);
- (void) sprintf (q, "-%d.%ds", SB_COLS - 22, SB_COLS - 22);
- (void) strcpy (&script_line[19], q);
-
- if ((Scrnbuf == NULL) ||
- (Sbuf.lcol == NULL) ||
- (Sbuf.rcol == NULL))
- {
- if (Scrnbuf != NULL)
- {
- free (Scrnbuf);
- Scrnbuf = NULL;
- }
- if (Sbuf.lcol != NULL)
- {
- free (Sbuf.lcol);
- Sbuf.lcol = NULL;
- }
- if (Sbuf.rcol != NULL)
- {
- free (Sbuf.rcol);
- Sbuf.rcol = NULL;
- }
-
- SB_ROWS = 23;
- SB_COLS = 80;
-
- Scrnbuf = (CELLP) calloc ((unsigned short) SB_ROWS * (unsigned short) SB_COLS, sizeof (CELL));
- Sbuf.bp = (CELLP) Scrnbuf;
-
- Sbuf.row = Sbuf.col = 0;
- Sbuf.lcol = (short *) calloc ((unsigned short) SB_COLS, sizeof (short));
- Sbuf.rcol = (short *) calloc ((unsigned short) SB_ROWS, sizeof (short));
-
- (void) sprintf (q, "-%d.%ds", SB_COLS - 16, SB_COLS - 16);
- (void) strcpy (&stat_str[19], q);
- (void) sprintf (q, "-%d.%ds", SB_COLS - 22, SB_COLS - 22);
- (void) strcpy (&script_line[19], q);
- }
-
- for (i = 0; i < (short) SB_ROWS; i++)
- {
- Sbuf.lcol[i] = SB_COLS;
- Sbuf.rcol[i] = 0;
- }
-
- Sbuf.flags = 0;
-
- c = Scrnbuf;
- for (i = 0; i < (short) SB_ROWS; i++)
- for (j = 0; j < (short) SB_COLS; j++)
- {
- (*c).cap = WHITEBLANK;
- ++c;
- }
- return;
- }
-
- void
- sb_move (REGIONP win, register short r, register short c)
- {
- /* don't change anything if request is out of range */
- if ((r < 0) || (r > (win->r1 - win->r0)) ||
- (c < 0) || (c > (win->c1 - win->c0)))
- return; /* (SB_ERR); */
-
- win->row = r;
- win->col = c;
- Sbuf.row = r + win->r0;
- Sbuf.col = c + win->c0;
-
- return; /* (SB_OK); */
- }
-
- void
- sb_caption (REGIONP Rgn, char *Caption)
- {
- sb_move (Rgn, 0, 1);
- sb_puts (Rgn, Caption);
- }
-
- REGIONP
- sb_new (short top, short left, short height, short width)
- {
- REGIONP new;
-
- new = calloc (1, sizeof (REGION));
- if (new != NULL)
- {
- new->r0 = new->sr0 = top;
- new->r1 = new->sr1 = top + height - 1;
- new->c0 = new->sc0 = left;
- new->c1 = new->sc1 = left + width - 1;
- new->row = new->col = 0;
- new->wflags = 0;
- }
- return (new);
- }
-
- int
- sb_popup (short top, short left, short height, short width,
- int (*func) (BINK_SAVEP, int), int arg)
- {
- int x;
- BINK_SAVEP tmp = (BINK_SAVEP) NULL;
-
- if (fullscreen && (un_attended || doing_poll))
- {
-
- tmp = sb_save (top, left, height, width);
- x = (*func) (tmp, arg);
- sb_restore (tmp);
- sb_show ();
- }
- else
- {
- x = (*func) (NULL, arg);
- }
- return (x);
- }
-
- int
- sb_putc (REGIONP win, short ch)
- {
- short cmax, rmax;
- int noscroll = 0, puterr = 0;
-
- /* calculate the screen buffer position and limits */
-
- cmax = win->c1 - win->c0;
- rmax = win->r1 - win->r0;
- Sbuf.row = win->r0 + win->row;
- Sbuf.col = win->c0 + win->col;
-
- /* process the character */
- switch (ch)
- {
- case '\b':
- /* Non destructive backspace */
- if (win->col > 0)
- {
- --(win->col);
- --(Sbuf.col);
- return (SB_OK);
- }
- else
- return (SB_ERR);
-
- case '\r':
- /* clear trailing line segment */
- while (win->col < cmax)
- {
- if (sb_putc (win, ' ') == SB_ERR)
- {
- ++puterr;
- }
- }
- sb_wc (win, ' ', 1);
- break;
-
- #ifdef TABEXP
- case '\t':
- /* convert tabs to spaces */
- lim = win->col + 8 - (win->col & 7);
- while (win->col < lim)
- {
- if (sb_putc (win, ' ') == SB_ERR)
- {
- ++puterr;
- }
- }
- break;
- #endif /* TABEXP */
-
- default:
- (Scrnbuf + Sbuf.row * SB_COLS + Sbuf.col)->b.ch = (unsigned char) ch;
-
- if (Sbuf.col < Sbuf.lcol[Sbuf.row])
- {
- Sbuf.lcol[Sbuf.row] = Sbuf.col;
- }
- if (Sbuf.col > Sbuf.rcol[Sbuf.row])
- {
- Sbuf.rcol[Sbuf.row] = Sbuf.col;
- }
- break;
- }
-
- /* update the cursor position */
- if (win->col < cmax)
- {
- ++(win->col);
- }
- else if (win->row < rmax)
- {
- win->col = 0;
- ++(win->row);
- }
- else if (win->wflags & SB_SCROLL)
- {
- sb_scrl (win, 1);
- win->col = 0;
- win->row = rmax;
- }
- else
- {
- ++noscroll;
- }
-
- /* update screen buffer position */
- Sbuf.row = win->r0 + win->row;
- Sbuf.col = win->c0 + win->col;
- Sbuf.flags |= SB_DELTA;
-
- return ((noscroll || puterr) ? SB_ERR : SB_OK);
- }
-
- void
- sb_puts (REGIONP win, char *s)
- {
- while (*s)
- {
- if (sb_putc (win, *s++) == SB_ERR)
- return; /* (SB_ERR); */
- }
-
- return; /* (SB_OK); */
- }
-
- unsigned char
- sb_ra (REGIONP win, short r, short c)
- {
- return ((unsigned char) (Scrnbuf + (win->r0 + r) * SB_COLS + win->c0 + c)->b.attr);
- }
-
- unsigned char
- sb_rc (REGIONP win, short r, short c)
- {
- return ((unsigned char) (Scrnbuf + (win->r0 + r) * SB_COLS + win->c0 + c)->b.ch);
- }
-
- unsigned int
- sb_rca (REGIONP win, short r, short c)
- {
- return ((unsigned int) (Scrnbuf + (win->r0 + r) * SB_COLS + win->c0 + c)->cap);
- }
-
- int
- sb_input_chars (REGIONP win, short row, short col, char *str, short len)
- {
- short i;
- short j;
-
- sb_move (win, row, col);
- for (i = 0; i < len; i++)
- (void) sb_putc (win, '_');
- sb_move (win, row, col);
-
- i = 0;
- while (i < len)
- {
- sb_show ();
- while (!KEYPRESS ())
- time_release ();
- j = FOSSIL_CHAR ();
- if ((j & 0xff) != 0)
- {
- j &= 0xff;
- j = toupper (j);
- if (isprint (j))
- {
- (void) sb_putc (win, (short) (j & 0xff));
- *str = (char) (j & 0xff);
- ++str;
- ++i;
- ++col;
- continue;
- }
- }
-
- switch (j)
- {
- case ESC:
- return (1);
-
- case BS:
- case LFAR:
- if (i > 0)
- {
- --col;
- sb_move (win, row, col);
- (void) sb_putc (win, '_');
- sb_move (win, row, col);
- --str;
- --i;
- }
- break;
-
- case CR:
- case LV:
- *str = '\0';
- for (j = i; j < len; j++)
- (void) sb_putc (win, ' ');
-
- if (i)
- return (0);
- else
- return (1);
- }
- }
-
- *str = '\0';
- sb_show ();
- return (0);
- }
-
- BINK_SAVEP
- sb_save (short top, short left, short height, short width)
- {
- BINK_SAVEP new;
- CELLP c;
- short i, j;
-
- new = calloc (1, sizeof (BINK_SAVE));
- c = new->save_cells = (CELLP) malloc (sizeof (CELL) * height * width);
- new->region = sb_new (top, left, height, width);
- new->save_row = (short) top;
- new->save_col = (short) left;
- new->save_ht = (short) height;
- new->save_wid = (short) width;
-
- j = top * SB_COLS + left;
- for (i = 0; i < height; i++)
- {
- (void) memcpy (&c[i * width], &Scrnbuf[j], width * sizeof (CELL));
- j += SB_COLS;
- }
-
- return (new);
- }
-
- void
- sb_restore (BINK_SAVEP save)
- {
- short i, j, r;
-
- j = save->save_row * SB_COLS + save->save_col;
- for (r = save->save_row, i = 0; i < save->save_ht; r++, i++)
- {
- (void) memcpy (&Scrnbuf[j], &(save->save_cells[i * save->save_wid]), save->save_wid * sizeof (CELL));
- j += SB_COLS;
- if (save->save_col < Sbuf.lcol[r])
- Sbuf.lcol[r] = save->save_col;
- if (save->save_col + save->save_wid > Sbuf.rcol[r])
- Sbuf.rcol[r] = save->save_col + save->save_wid;
- }
-
- Sbuf.flags |= SB_DELTA;
-
- free ((char *) (save->save_cells));
- free (save->region);
- free (save);
- }
-
- void
- sb_scrl (REGIONP win, short n)
- {
- register short r, c;
-
- c = win->sc0;
- if (n == 0)
- {
- /* clear the entire region to spaces */
- sb_fillc (win, ' ');
- }
- else if (n > 0)
- {
- /* scroll n rows up */
- for (r = win->sr0; r <= win->sr1 - n; r++)
- {
- (void) memcpy (Scrnbuf + r * SB_COLS + c, Scrnbuf + (r + n) * SB_COLS + c,
- (unsigned short) (win->sc1 - win->sc0 + 1) * 2);
-
- if (win->sc0 < Sbuf.lcol[r])
- {
- Sbuf.lcol[r] = win->sc0;
- }
- if (win->sc1 > Sbuf.rcol[r])
- {
- Sbuf.rcol[r] = win->sc1;
- }
- }
- for (; r <= win->sr1; r++)
- {
- for (c = win->sc0; c <= win->sc1; c++)
- {
- (Scrnbuf + r * SB_COLS + c)->b.ch = ' ';
- }
- if (win->sc0 < Sbuf.lcol[r])
- {
- Sbuf.lcol[r] = win->sc0;
- }
- if (win->sc1 > Sbuf.rcol[r])
- {
- Sbuf.rcol[r] = win->sc1;
- }
- }
- }
- else
- {
- /* scroll n rows down */
- n = -n;
- for (r = win->sr1; r >= win->sr0 + n; r--)
- {
- (void) memcpy (Scrnbuf + r * SB_COLS + c, Scrnbuf + (r - n) * SB_COLS + c,
- (unsigned short) (win->sc1 - win->sc0 + 1) * 2);
- if (win->sc0 < Sbuf.lcol[r])
- {
- Sbuf.lcol[r] = win->sc0;
- }
- if (win->sc1 > Sbuf.rcol[r])
- {
- Sbuf.rcol[r] = win->sc1;
- }
- }
- for (; r >= win->sr0; r--)
- {
- for (c = win->sc0; c <= win->sc1; c++)
- {
- (Scrnbuf + r * SB_COLS + c)->b.ch = ' ';
- }
- if (win->sc0 < Sbuf.lcol[r])
- {
- Sbuf.lcol[r] = win->sc0;
- }
- if (win->sc1 > Sbuf.rcol[r])
- {
- Sbuf.rcol[r] = win->sc1;
- }
- }
- }
-
- Sbuf.flags |= SB_DELTA;
-
- return;
- }
-
- void
- sb_show ()
- {
- register short r;
- unsigned short src_os;
- char far *q;
-
- if (screen_blank && do_screen_blank)
- {
- for (r = 0; r < SB_ROWS; r++)
- {
- q = blanks;
- (void) VioWrtCellStr ((PCH) q, (USHORT) (SB_COLS * 2), (USHORT) r, (USHORT) 0, (HVIO) 0L);
- }
- sb_dirty ();
- return;
- }
-
- /* Anything to do? */
- if (!(Sbuf.flags & SB_DELTA))
- {
- return;
- }
-
- src_os = 0;
- for (r = 0; r < SB_ROWS; r++)
- {
- /* Copy only changed portions of lines */
- if ((Sbuf.lcol[r] < SB_COLS) && (Sbuf.rcol[r] > 0))
- {
- q = (char far *) (Scrnbuf + src_os + Sbuf.lcol[r]);
- (void) VioWrtCellStr ((PCH) q, (USHORT) ((Sbuf.rcol[r] - Sbuf.lcol[r] + 1) * 2), (USHORT) r, (USHORT) Sbuf.lcol[r], (HVIO) 0L);
- Sbuf.lcol[r] = SB_COLS;
- Sbuf.rcol[r] = 0;
- }
- src_os += (unsigned short) SB_COLS;
- }
-
- /* the display now matches the buffer -- clear flag bit */
- Sbuf.flags &= ~SB_DELTA;
-
- /* Put sanity check on cursor_row and cursor_col here */
- if (cursor_row < 0 || cursor_row > (short) (SB_ROWS - 1))
- cursor_row = SB_ROWS - 1;
- if (cursor_col < 0 || cursor_col > (short) (SB_COLS - 1))
- cursor_col = SB_COLS - 1;
-
- gotoxy (cursor_col, cursor_row);
- return;
- }
-
- /*
- * Just cleans up the structure to say it is reality - I can use this when
- * I write directly to the screen for single char writes.
- */
-
- void
- sb_clean ()
- {
- short r;
-
- for (r = 0; r < (short) SB_ROWS; r++)
- {
- Sbuf.lcol[r] = SB_COLS;
- Sbuf.rcol[r] = 0;
- }
-
- Sbuf.flags &= ~SB_DELTA;
- }
-
- /*
- * Make the entire buffer "dirty" so it will be updated.
- */
-
- void
- sb_dirty ()
- {
- short r;
-
- for (r = 0; r < (short) SB_ROWS; r++)
- {
- Sbuf.lcol[r] = 0;
- Sbuf.rcol[r] = SB_COLS_M_1;
- }
-
- Sbuf.flags |= SB_DELTA;
- }
-
- void
- sb_wa (REGIONP win, short attr, short n)
- {
- short i;
- short row;
- short col;
-
- i = n;
- row = win->r0 + win->row;
- col = win->c0 + win->col;
-
- while (i--)
- (Scrnbuf + row * SB_COLS + col + i)->b.attr = (unsigned char) attr;
-
- /* marked the changed region */
- if (col < Sbuf.lcol[row])
- Sbuf.lcol[row] = col;
- if (col + n > Sbuf.rcol[row])
- Sbuf.rcol[row] = col + n;
-
- Sbuf.flags |= SB_DELTA;
-
- return; /* ((i == 0) ? SB_OK : SB_ERR); */
- }
-
- void
- sb_wc (REGIONP win, short ch, short n)
- {
- short i;
- short row;
- short col;
-
- i = n;
- row = win->r0 + win->row;
- col = win->c0 + win->col;
-
- while (i--)
- (Scrnbuf + row * SB_COLS + col + i)->b.ch = (unsigned char) ch;
-
- /* marked the changed region */
- if (col < Sbuf.lcol[row])
- Sbuf.lcol[row] = col;
- if (col + n > Sbuf.rcol[row])
- Sbuf.rcol[row] = col + n;
-
- Sbuf.flags |= SB_DELTA;
-
- return; /* ((i == 0) ? SB_OK : SB_ERR); */
- }
-
- void
- sb_wca (REGIONP win, short ch, short attr, short n)
- {
- short i;
- short row;
- short col;
- unsigned short ca;
-
- i = n;
- ca = (((unsigned short) attr) << 8) | (unsigned short) ch;
- row = win->r0 + win->row;
- col = win->c0 + win->col;
-
- while (i--)
- (Scrnbuf + row * SB_COLS + col + i)->cap = ca;
-
- /* marked the changed region */
- if (col < Sbuf.lcol[row])
- Sbuf.lcol[row] = col;
- if (col + n > Sbuf.rcol[row])
- Sbuf.rcol[row] = col + n;
-
- Sbuf.flags |= SB_DELTA;
-
- return; /* ((i == 0) ? SB_OK : SB_ERR); */
- }
-