home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name scwrrect -- Write rectangular region on
- * the current display page via BIOS
- *
- * Synopsis num_writ = scwrrect(u_row,u_col,l_row,l_col,
- * buffer,fore,back,option);
- *
- * int num_writ Number of character cells actually written
- * int u_row Top row to write (0 = top of screen)
- * int u_col Leftmost column to write (0 = left edge)
- * int l_row Bottom row to write
- * int l_col Rightmost column to write
- * char *buffer Space containing the data to write
- * int fore -1 if existing foreground is to be
- * preserved;
- * if CHARS_ONLY is specified, a value
- * between 0 and 15 specifies a new
- * foreground attribute.
- * int back -1 if existing background is to be
- * preserved;
- * if CHARS_ONLY is specified, a value
- * between 0 and 15 specifies a new
- * background attribute.
- * int option One bit in the option value tells SCWRRECT
- * how the buffer is constructed. The two
- * possible values for this bit are:
- *
- * Value Meaning
- * ----------- ------------------------------------
- * CHARS_ONLY Buffer contains characters only.
- * The values of fore and back are used
- * as attributes.
- * CHAR_ATTR Buffer contains (char,attr) pairs.
- * The values of fore and back are
- * ignored unless they are -1.
- *
- * Description This function fills a rectangular region on the current
- * display page with characters from a buffer with or
- * without their corresponding video attributes. The data
- * is written row by row. The cursor is not moved.
- *
- * The upper left corner of the region is (u_row,u_col),
- * where (0,0) represents the upper left corner of the
- * entire screen. The lower right corner of the region is
- * (l_row,l_col), where (24,79) is the lower right corner
- * of an 80-by-25 screen.
- *
- * The returned value reports the number of "character
- * cells" written, where "character cells" means the number
- * of physical spaces on the screen. (If option CHAR_ATTR
- * is specified, twice this number of bytes will be used
- * from the buffer.)
- *
- * 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 and CHAR_ATTR is specified, then specifying -1 for
- * fore will cause color 1 to be used.
- *
- * Be aware that this function does NOT recognize NULs
- * ('\0') or any other special characters.
- *
- * Use VIWRRECT for greater speed in text modes.
- *
- * Returns num_writ Number of character cells written
- *
- * Version 3.0 (C)Copyright Blaise Computing Inc. 1986
- *
- **/
-
- #include <bscreen.h>
-
- int scwrrect(u_row,u_col,l_row,l_col,buffer,fore,back,option)
- int u_row,u_col,l_row,l_col;
- char *buffer;
- int fore,back,option;
- {
- int ax,bx,cx,dx,flags;
- int mode,columns,act_page,last_row;
- int row,col,save_row,save_col;
- int want_attr,oldmask,newmask,old_attr,new_attr;
- int cursor_was_on,top_scan,bot_scan;
-
- scmode(&mode,&columns,&act_page);
- last_row = scrows() - 1;
-
- utbound(u_row,0, last_row) /* Force reasonable values */
- utbound(l_row,u_row,last_row)
- utbound(u_col,0, columns - 1)
- utbound(l_col,u_col,columns - 1)
-
- /* Set various flags which will remain constant through the main */
- /* loop. */
-
- if (mode > 3 && mode != 7) /* Graphics mode: */
- { /* Ignore previous attributes */
- if (fore == -1) /* since we can't read them. */
- fore = 1;
- back = 0; /* Nonzero background causes */
- /* trouble. */
- oldmask = 0x00; /* Ignore previous attributes. */
-
- }
- else /* Text mode: */
- {
- 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;
- }
-
- newmask = 0xff & ~oldmask; /* "newmask" will help us */
- /* extract the relevant */
- /* portion(s) of the new */
- /* attributes */
-
- new_attr = utnybbyt(back,fore) & newmask;
- if (oldmask == 0x00)
- old_attr = 0;
- want_attr = ((option & CHAR_ATTR) != 0);
- bx = utbyword(b_curpage,0);
- cx = 1;
-
- /* Main loop */
-
- /* Save cursor size & position. */
- if (cursor_was_on = !sccurst(&save_row,&save_col,&top_scan,&bot_scan))
- /* Turn the cursor off */
- scpgcur(1,top_scan,bot_scan,CUR_NO_ADJUST);
- for (row = u_row; row <= l_row; row++)
- for (col = u_col; col <= l_col; col++)
- {
- ax = utbyword(2,0); /* Move cursor to (row,col) */
- dx = utbyword(row,col);
- bios(16,&ax,&bx,&cx,&dx,&flags);
-
- if (oldmask == 0xff)
- { /* Ignoring old attribute */
- ax = utbyword(10,*buffer++);
- if (want_attr)
- buffer++;
- bx = utbyword(b_curpage,0);
- bios(16,&ax,&bx,&cx,&dx,&flags);
- }
- else
- { /* Write character with */
- /* attributes */
- if (oldmask)
- { /* Retrieve previous attributes */
- ax = utbyword(8,0);
- bios(16,&ax,&bx,&cx,&dx,&flags);
- old_attr = uthibyte(ax) & oldmask;
- }
- /* Now old_attr holds the */
- /* portion of the previous */
- /* attributes which we must */
- /* preserve. */
-
- ax = utbyword(9,*buffer++); /* Write char & attribute */
- if (want_attr)
- bx=utbyword(b_curpage,old_attr|((int)*buffer++&newmask));
- else
- bx=utbyword(b_curpage,old_attr|new_attr);
-
- bios(16,&ax,&bx,&cx,&dx,&flags);
- }
- }
-
- sccurset(save_row,save_col);
- if (cursor_was_on) /* Restore cursor size. */
- scpgcur(0,top_scan,bot_scan,CUR_NO_ADJUST);
- return (l_row - u_row + 1) * (l_col - u_col + 1);
- }