home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name scwrbuf -- Write a stream of adjacent characters
- * to the current display page via BIOS
- *
- * Synopsis num_writ = scwrbuf(row,col,num_spaces,buffer,fore,back,
- * option);
- *
- * int num_writ Number of spaces actually written
- * int row,col Row and column at which to begin writing
- * int num_spaces Number of character cells to write.
- * If CHARS_ONLY is specified (see "option"
- * below), num_spaces == 0 indicates that
- * the buffer is terminated by a NUL ('\0')
- * character.
- * char *buffer 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 The option value tells SCWRBUF how the
- * buffer is constructed and where to
- * position the cursor after the buffer has
- * been written. Three different bits are
- * relevant:
- *
- * Value Meaning
- * ----------- ------------------------------------
- * CUR_BEG Leave cursor at (row,col).
- * CUR_AFTER Leave cursor after end of string.
- *
- * CHARS_ONLY Buffer contains characters only.
- * If num_spaces is zero, the string
- * is terminated by a NUL ('\0')
- * character.
- * CHAR_ATTR Buffer contains (char,attr) pairs.
- *
- * MOVE_CUR Leave cursor according to
- * CUR_BEG/CUR_AFTER bit.
- * NO_MOVE_CUR Preserve cursor location.
- *
- * Description This function writes characters to the current display
- * page with or without their corresponding video
- * attributes. It can leave the cursor at the beginning or
- * end of the space written to or leave the cursor unmoved.
- *
- * This routine will not scroll the screen, although it
- * wraps text from one line to the next.
- *
- * If the num_spaces argument is nonzero, it specifies the
- * number of physical spaces to write, (If CHAR_ATTR is
- * specified, twice this number of bytes will be used from
- * the buffer.) If num_spaces exceeds the number of
- * characters to the end of the line, the write will
- * continue on the following line, and so on to the end of
- * the screen. The write will stop at the end of the
- * screen, hence the number of spaces actually written may
- * be less than what the buffer contains. The actual
- * number is returned as the value of the function.
- *
- * If the write includes the lower right corner of the
- * screen, then the cursor is left at the lower right
- * corner if option bits CUR_AFTER and MOVE_CUR are
- * specified.
- *
- * This function only recognizes NULs ('\0') as the end of
- * the buffer if num_spaces is zero and if CHARS_ONLY is
- * specified. This function does not recognize any other
- * special characters.
- *
- * Returns num_writ Number of spaces written
- *
- * Version 3.0 (C)Copyright Blaise Computing Inc. 1986
- *
- **/
-
- #include <string.h>
-
- #include <bscreen.h>
-
- int scwrbuf(row,col,num_spaces,buffer,fore,back,option)
- register int row,col;
- int num_spaces;
- char *buffer;
- int fore,back,option;
- {
- int ax,bx,cx,dx,flags;
- int mode,columns,last_row,act_page;
- int want_attr,oldmask,newmask,old_attr,new_attr;
- int save_row,save_col,save_num;
- int cursor_was_on,top_scan,bot_scan;
-
- scmode(&mode,&columns,&act_page);
- last_row = scrows() - 1;
-
- want_attr = ((option & CHAR_ATTR) != 0); /* want_attr == 1 means */
- /* that we must get the new */
- /* attribute values from buffer.*/
-
- /* Force reasonable values */
-
- utbound(row,0,last_row)
- utbound(col,0,columns - 1)
- if ((!want_attr) && num_spaces == 0)
- num_spaces = (int) strlen(buffer);
- utuplim(num_spaces,columns - col + ((last_row - row) * columns))
-
- /* 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);
- if (0 == (option & NO_MOVE_CUR))
- {
- save_row = row; /* Beginning of string. */
- save_col = col;
- }
- save_num = num_spaces;
-
- /* Set various flags which will remain constant through the main */
- /* loop. */
-
- if (mode > 3 && mode != 7)/* Graphics mode: Ignore previous */
- { /* attributes since we can't read them. */
- if (fore == -1)
- fore = 1;
- back = 0; /* Nonzero background causes trouble. */
- oldmask = 0x00; /* Ignore previous attributes. */
-
- }
- else /* Text mode: */
- {
- if (fore == -1) /* "oldmask" will help us extract the */
- oldmask = 0x0f; /* portion(s) of the previous attributes*/
- else /* which must be preserved. */
- oldmask = 0x00;
- 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;
- bx = utbyword(b_curpage,0);
- cx = 1;
-
- /* Main loop */
-
- sccurset(row,col);
- while (num_spaces--)
- {
- if (oldmask == 0xff)
- { /* Write character only */
- 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 != 0x00)
- { /* 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);
- }
-
- if (++col >= columns)
- { /* Start next row */
- col = 0;
- row++;
- }
- ax = utbyword(2,0); /* Set cursor position */
- dx = utbyword(row,col);
- bios(16,&ax,&bx,&cx,&dx,&flags);
- /* Cursor is left after each */
- /* character written. */
- }
-
- if ((option & NO_MOVE_CUR) || !(option & CUR_AFTER))
- sccurset(save_row,save_col); /* Restore cursor position */
- /* (either to previous location */
- /* or to beginning of string). */
-
- if (cursor_was_on) /* Restore cursor size. */
- scpgcur(0,top_scan,bot_scan,CUR_NO_ADJUST);
-
- return save_num;
- }