home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c005 / 4.ddi / C / SCWRBUF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-08-05  |  6.9 KB  |  214 lines

  1. /**
  2. *
  3. * Name        scwrbuf -- Write a stream of adjacent characters
  4. *               to the current display page via BIOS
  5. *
  6. * Synopsis    num_writ = scwrbuf(row,col,num_spaces,buffer,fore,back,
  7. *                   option);
  8. *
  9. *        int  num_writ    Number of spaces actually written
  10. *        int  row,col    Row and column at which to begin writing
  11. *        int  num_spaces Number of character cells to write.
  12. *                If CHARS_ONLY is specified (see "option"
  13. *                below), num_spaces == 0 indicates that
  14. *                the buffer is terminated by a NUL ('\0')
  15. *                character.
  16. *        char *buffer    Data to write
  17. *        int  fore    -1 if existing foreground is to be
  18. *                preserved;
  19. *                if CHARS_ONLY is specified, a value
  20. *                between 0 and 15 specifies a new
  21. *                foreground attribute.
  22. *        int  back    -1 if existing background is to be
  23. *                preserved;
  24. *                if CHARS_ONLY is specified, a value
  25. *                between 0 and 15 specifies a new
  26. *                background attribute.
  27. *        int  option    The option value tells SCWRBUF how the
  28. *                buffer is constructed and where to
  29. *                position the cursor after the buffer has
  30. *                been written.  Three different bits are
  31. *                relevant:
  32. *
  33. *              Value        Meaning
  34. *              -----------   ------------------------------------
  35. *              CUR_BEG        Leave cursor at (row,col).
  36. *              CUR_AFTER     Leave cursor after end of string.
  37. *
  38. *              CHARS_ONLY    Buffer contains characters only.
  39. *                    If num_spaces is zero, the string
  40. *                    is terminated by a NUL ('\0')
  41. *                    character.
  42. *              CHAR_ATTR     Buffer contains (char,attr) pairs.
  43. *
  44. *              MOVE_CUR        Leave cursor according to
  45. *                      CUR_BEG/CUR_AFTER bit.
  46. *              NO_MOVE_CUR   Preserve cursor location.
  47. *
  48. * Description    This function writes characters to the current display
  49. *        page with or without their corresponding video
  50. *        attributes.  It can leave the cursor at the beginning or
  51. *        end of the space written to or leave the cursor unmoved.
  52. *
  53. *        This routine will not scroll the screen, although it
  54. *        wraps text from one line to the next.
  55. *
  56. *        If the num_spaces argument is nonzero, it specifies the
  57. *        number of physical spaces to write, (If CHAR_ATTR is
  58. *        specified, twice this number of bytes will be used from
  59. *        the buffer.)  If num_spaces exceeds the number of
  60. *        characters to the end of the line, the write will
  61. *        continue on the following line, and so on to the end of
  62. *        the screen.  The write will stop at the end of the
  63. *        screen, hence the number of spaces actually written may
  64. *        be less than what the buffer contains.    The actual
  65. *        number is returned as the value of the function.
  66. *
  67. *        If the write includes the lower right corner of the
  68. *        screen, then the cursor is left at the lower right
  69. *        corner if option bits CUR_AFTER and MOVE_CUR are
  70. *        specified.
  71. *
  72. *        This function only recognizes NULs ('\0') as the end of
  73. *        the buffer if num_spaces is zero and if CHARS_ONLY is
  74. *        specified.  This function does not recognize any other
  75. *        special characters.
  76. *
  77. * Returns    num_writ    Number of spaces written
  78. *
  79. * Version    3.0  (C)Copyright Blaise Computing Inc. 1986
  80. *
  81. **/
  82.  
  83. #include <string.h>
  84.  
  85. #include <bscreen.h>
  86.  
  87. int scwrbuf(row,col,num_spaces,buffer,fore,back,option)
  88. register int row,col;
  89. int         num_spaces;
  90. char         *buffer;
  91. int         fore,back,option;
  92. {
  93.     int ax,bx,cx,dx,flags;
  94.     int mode,columns,last_row,act_page;
  95.     int want_attr,oldmask,newmask,old_attr,new_attr;
  96.     int save_row,save_col,save_num;
  97.     int cursor_was_on,top_scan,bot_scan;
  98.  
  99.     scmode(&mode,&columns,&act_page);
  100.     last_row = scrows() - 1;
  101.  
  102.     want_attr = ((option & CHAR_ATTR) != 0);  /* want_attr == 1 means */
  103.                       /* that we must get the new     */
  104.                       /* attribute values from buffer.*/
  105.  
  106.     /* Force reasonable values                          */
  107.  
  108.     utbound(row,0,last_row)
  109.     utbound(col,0,columns - 1)
  110.     if ((!want_attr) && num_spaces == 0)
  111.     num_spaces = (int) strlen(buffer);
  112.     utuplim(num_spaces,columns - col + ((last_row - row) * columns))
  113.  
  114.                       /* Save cursor size & position. */
  115.     if (cursor_was_on = !sccurst(&save_row,&save_col,&top_scan,&bot_scan))
  116.                       /* Turn the cursor off          */
  117.     scpgcur(1,top_scan,bot_scan,CUR_NO_ADJUST);
  118.     if (0 == (option & NO_MOVE_CUR))
  119.     {
  120.     save_row = row;           /* Beginning of string.          */
  121.     save_col = col;
  122.     }
  123.     save_num = num_spaces;
  124.  
  125.     /* Set various flags which will remain constant through the main  */
  126.     /* loop.                                  */
  127.  
  128.     if (mode > 3 && mode != 7)/* Graphics mode:  Ignore previous      */
  129.     {                  /* attributes since we can't read them. */
  130.     if (fore == -1)
  131.         fore = 1;
  132.     back     = 0;          /* Nonzero background causes trouble.   */
  133.     oldmask  = 0x00;      /* Ignore previous attributes.          */
  134.  
  135.     }
  136.     else              /* Text mode:                  */
  137.     {
  138.     if (fore == -1)       /* "oldmask" will help us extract the   */
  139.         oldmask  = 0x0f;  /* portion(s) of the previous attributes*/
  140.     else              /* which must be preserved.          */
  141.         oldmask  = 0x00;
  142.     if (back == -1)
  143.         oldmask |= 0xf0;
  144.     }
  145.  
  146.     newmask = 0xff & ~oldmask;/* "newmask" will help us extract the   */
  147.                   /* relevant portion(s) of the new       */
  148.                   /* attributes                  */
  149.  
  150.     new_attr = utnybbyt(back,fore) & newmask;
  151.     if (oldmask == 0x00)
  152.     old_attr = 0;
  153.     bx         = utbyword(b_curpage,0);
  154.     cx         = 1;
  155.  
  156.     /* Main loop                              */
  157.  
  158.     sccurset(row,col);
  159.     while (num_spaces--)
  160.     {
  161.     if (oldmask == 0xff)
  162.     {                  /* Write character only          */
  163.         ax = utbyword(10,*buffer++);
  164.         if (want_attr)
  165.         buffer++;
  166.         bx = utbyword(b_curpage,0);
  167.         bios(16,&ax,&bx,&cx,&dx,&flags);
  168.     }
  169.     else
  170.     {                  /* Write character with          */
  171.                       /* attributes              */
  172.         if (oldmask != 0x00)
  173.         {                  /* Retrieve previous attributes */
  174.         ax = utbyword(8,0);
  175.         bios(16,&ax,&bx,&cx,&dx,&flags);
  176.         old_attr = uthibyte(ax) & oldmask;
  177.         }
  178.                   /* Now old_attr holds the portion of    */
  179.                   /* the previous attributes which we     */
  180.                   /* must preserve.               */
  181.  
  182.         ax = utbyword(9,*buffer++);   /* Write char & attribute   */
  183.  
  184.         if (want_attr)
  185.         bx = utbyword(b_curpage,old_attr | ((int)*buffer++ & newmask));
  186.         else
  187.         bx = utbyword(b_curpage,old_attr | new_attr);
  188.  
  189.         bios(16,&ax,&bx,&cx,&dx,&flags);
  190.     }
  191.  
  192.     if (++col >= columns)
  193.     {                  /* Start next row           */
  194.         col = 0;
  195.         row++;
  196.     }
  197.     ax = utbyword(2,0);          /* Set cursor position          */
  198.     dx = utbyword(row,col);
  199.     bios(16,&ax,&bx,&cx,&dx,&flags);
  200.                       /* Cursor is left after each    */
  201.                       /* character written.          */
  202.     }
  203.  
  204.     if ((option & NO_MOVE_CUR) || !(option & CUR_AFTER))
  205.     sccurset(save_row,save_col);  /* Restore cursor position      */
  206.                       /* (either to previous location */
  207.                       /* or to beginning of string).  */
  208.  
  209.     if (cursor_was_on)              /* Restore cursor size.          */
  210.     scpgcur(0,top_scan,bot_scan,CUR_NO_ADJUST);
  211.  
  212.     return save_num;
  213. }
  214.