home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name scttywin -- Write a character to a rectangular region
- * on the current display page via BIOS,
- * TTY-style.
- *
- * Synopsis scttywin(u_row,u_col,l_row,l_col,
- * ch,fore,back,scr_fore,scr_back);
- *
- * int u_row Top row of region (0 = top of screen)
- * int u_col Leftmost column of region (0 = left edge)
- * int l_row Bottom row of region
- * int l_col Rightmost column of region
- * char ch Character to write
- * int fore -1 if existing foreground is to be
- * preserved; a value between 0 and 15
- * specifies a new foreground attribute.
- * int back -1 if existing background is to be
- * preserved; a value between 0 and 15
- * specifies a new background attribute.
- * int scr_fore Foreground attribute of blank lines
- * added when scrolling (-1 to use
- * foreground attribute of character
- * position before scroll).
- * int scr_back Background attribute of blank lines
- * added when scrolling (-1 to use
- * background attribute of character
- * position before scroll).
- *
- * Description This function writes a character to a rectangular region
- * on the current display page in the manner of a teletype.
- * It treats carriage return, line feed, backspace, and
- * bell as commands rather than as printable characters.
- * All output and scrolling are confined to the region.
- *
- * If the cursor is currently within the region, the
- * character is written at that point. If the cursor is
- * not within the region, the character is written at the
- * upper left corner of the region. The cursor is left
- * after the displayed character.
- *
- * If the screen is in a text mode, specifying -1 for fore
- * or back preserves the existing foreground or background
- * attributes, respectively. This will occur regardless of
- * the value of option. If the screen is in a graphics
- * mode, then specifying -1 for fore will cause color 1 to
- * be used.
- *
- * The region is scrolled if a line feed occurs on the last
- * row of the region or if the last row is overflowed,
- * except that scrolling will not take place on an inactive
- * page in graphics mode.
- *
- * If the screen is scrolled in text mode due to a line
- * feed character and scr_fore or scr_back is -1, then the
- * foreground or background attribute(s) (respectively) for
- * the new blank row are taken from the character position
- * last occupied before the scroll. If the scroll is
- * caused by overflowing the last row of the region and
- * scr_fore or scr_back is -1, the respective attribute(s)
- * are taken from the former attribute at the leftmost
- * column of the bottom row. Otherwise the value of
- * scr_fore or scr_back is used. (When scr_fore and
- * scr_back are both -1, this uses the same convention as
- * SCTTYWRT.)
- *
- * If the screen is scrolled in a graphics mode, the
- * scrolled text is given the color specified by scr_fore,
- * unless scr_fore is -1, in which case color 1 is used.
- *
- * Limitation This function will not scroll the region in graphics
- * mode if the current page is not active.
- *
- * Example This statement:
- *
- * scttywrt(ch,fore);
- *
- * is equivalent to the following in text modes:
- *
- * scttywin(0,0,PC_BIG_ROWS,PC_COLS,
- * ch,-1,-1,-1,-1);
- *
- * and to the following in graphics modes (if the current
- * page is active):
- *
- * scttywin(0,0,PC_BIG_ROWS,PC_COLS,
- * ch,fore,-1,fore,-1);
- *
- * provided that fore is not -1.
- *
- * Special Tab characters ('\t') are displayed literally.
- * characters
- * NUL ('\0') is a printable character (printed as a blank
- * space).
- *
- * Line feed ('\12') causes the cursor to move down one
- * row, unless it is already on the bottom row of the
- * region, in which case the screen is scrolled.
- *
- * Carriage return ('\r') causes the cursor to move to the
- * leftmost column of the region.
- *
- * Backspace ('\b') causes the cursor to move one column to
- * the left (non-destructively), unless it is already at
- * the leftmost column of the region, in which case nothing
- * happens.
- *
- * The BEL character ('\7') causes the computer's bell to
- * sound if the current page is active.
- *
- * Returns (None. Function return type is void.)
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1986-1989
- *
- **/
-
- #include <dos.h>
-
- #include <bscreens.h>
- #include <bvideo.h>
-
- #define BEL '\7'
- #define BS '\b'
- #define CR '\r'
- #define LF '\12'
-
- void scttywin(u_row,u_col,l_row,l_col,ch,fore,back,scr_fore,scr_back)
- int u_row,u_col,l_row,l_col;
- char ch;
- int fore,back,scr_fore,scr_back;
- {
- union REGS inregs,outregs; /* Registers for BIOS calls */
- int mode,act_page,columns,last_row;
- int oldmask,old_attr;
- int high,low,row,col;
-
- scmode(&mode,&columns,&act_page);
- last_row = scrows() - 1;
- last_row--;
-
- utbound(u_row,0,last_row) /* Force reasonable values */
- utbound(u_col,0,columns - 1)
- utbound(l_row,u_row,last_row)
- utbound(l_col,u_col,columns - 1)
-
- sccurst(&row,&col,&high,&low);
- if (utrange(row,u_row,l_row) || utrange(col,u_col,l_col))
- sccurset((row = u_row),(col = u_col));
-
- switch (ch)
- {
- case BEL:
- if (b_curpage == act_page)
- scttywrt(ch,0); /* Don't beep on inactive page */
- break;
-
- case BS:
- if (col > u_col) /* Don't back up past first */
- sccurset(row,col - 1); /* column */
- break;
-
- case CR:
- sccurset(row,u_col); /* Beginning of current line */
- break;
-
- default: /* First write the character */
-
- if (fore == -1) /* "oldmask" will help us */
- oldmask = 0x0f; /* extract the portion(s) of */
- else /* the previous attributes */
- oldmask = 0x00; /* which must be preserved. */
- if (back == -1)
- oldmask |= 0xf0;
-
- if (oldmask == 0xff)
- { /* Write character only */
- inregs.h.ah = 10;
- inregs.h.al = ch;
- inregs.h.bh = (unsigned char) b_curpage;
- }
- else
- { /* Write character with */
- /* attributes */
- if (oldmask != 0x00)
- {
- inregs.h.ah = 8;
- inregs.h.bh = (unsigned char) b_curpage;
- int86(16,&inregs,&outregs);
- old_attr = outregs.h.ah & oldmask;
- }
- else
- old_attr = 0;
-
- inregs.h.ah = 9;
- inregs.h.al = ch;
- inregs.h.bh = (unsigned char) b_curpage;
- inregs.h.bl = (unsigned char) (old_attr |
- (utnybbyt(back,fore) & ~oldmask));
- }
- inregs.x.cx = 1;
- int86(16,&inregs,&outregs); /* Actually write it */
-
- inregs.h.ah = 2;
- inregs.h.bh = (unsigned char) b_curpage;
- if (++col <= l_col) /* Check for possible wrap */
- { /* This fits on current line */
- inregs.h.dh = (unsigned char) row;
- inregs.h.dl = (unsigned char) col;
- int86(16,&inregs,&outregs);
- break;
- }
- /* Wrap to next line */
- col = u_col;
- inregs.h.dh = (unsigned char) row;
- inregs.h.dl = (unsigned char) col;
- int86(16,&inregs,&outregs);
- case LF:
- if (row < l_row)
- { /* No need to scroll */
- sccurset(row + 1,col);
- break;
- }
- /* Obtain attribute with which */
- /* to fill new bottom line. */
-
- scread(&fore,&back); /* Obtain attribute from */
- /* previous cursor position */
- if (scr_fore == -1)
- scr_fore = fore;
- if (scr_back == -1)
- scr_back = back;
-
- /* Scroll up. */
- viscroll(1,
- utnybbyt(scr_back,scr_fore),
- u_row,u_col,
- l_row,l_col,
- SCR_UP);
- break;
- }
- }