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

  1. /**
  2. *
  3. * Name        scwrstr -- Write a string of characters to the current
  4. *               display page via BIOS, TTY-style
  5. *
  6. * Synopsis    scwrstr(row,col,num_spaces,buffer,fore,back,option);
  7. *
  8. *        int  row,col    Row and column at which to begin writing
  9. *        int  num_spaces Number of character cells to write;
  10. *                if CHARS_ONLY is set (see "option" below),
  11. *                num_spaces == 0 means the buffer is
  12. *                terminated by a NUL ('\0') character.
  13. *        char *buffer    Data to write
  14. *        int  fore    -1 if existing foreground is to be
  15. *                preserved;
  16. *                if CHARS_ONLY is specified, a value
  17. *                between 0 and 15 specifies a new
  18. *                foreground attribute.
  19. *        int  back    -1 if existing background is to be
  20. *                preserved;
  21. *                if CHARS_ONLY is specified, a value
  22. *                between 0 and 15 specifies a new
  23. *                background attribute.
  24. *        int  option    The option value tells SCWRSTR how the
  25. *                buffer is constructed and where to
  26. *                position the cursor after the buffer has
  27. *                been written.  There are three relevant
  28. *                bits:
  29. *
  30. *              Value        Meaning
  31. *              -----------   ------------------------------------
  32. *              CUR_BEG        Leave cursor at (row,col).
  33. *              CUR_AFTER     Leave cursor after end of string.
  34. *
  35. *              CHARS_ONLY    Buffer contains characters only.
  36. *                    If num_spaces is zero, the string
  37. *                    is terminated by a NUL ('\0')
  38. *                    character.
  39. *              CHAR_ATTR     Buffer contains (char,attr) pairs.
  40. *
  41. *              MOVE_CUR        Leave cursor according to
  42. *                      CUR_BEG/CUR_AFTER bit.
  43. *              NO_MOVE_CUR   Preserve cursor location.
  44. *
  45. * Description    This function writes characters to the current display
  46. *        page with or without their corresponding video
  47. *        attributes.  It can leave the cursor at the beginning or
  48. *        end of the space written to or leave the cursor unmoved.
  49. *        It treats carriage return, line feed, backspace, and
  50. *        bell as commands rather than as printable characters.
  51. *
  52. *        If the num_spaces argument is nonzero, it specifies the
  53. *        number of "character cells" to write, where "character
  54. *        cells" means the number of actual characters in the
  55. *        buffer.  (If CHAR_ATTR is specified, twice this number
  56. *        of bytes will be used from the buffer.)
  57. *
  58. *        The screen is scrolled if a line feed occurs on the last
  59. *        line or if the last line is overflowed.  If MOVE_CUR and
  60. *        CUR_BEG are both specified, the cursor will be left at
  61. *        (row,col) even though the screen has been scrolled.
  62. *
  63. *        If the screen is in a text mode, specifying -1 for fore
  64. *        or back preserves the existing foreground or background
  65. *        attributes, respectively.  This will occur regardless of
  66. *        the value of option.  If the screen is in a graphics
  67. *        mode and CHARS_ONLY is specified, then specifying -1 for
  68. *        fore will cause color 1 to be used.
  69. *
  70. *        Be aware that this routine treats NUL ('\0') as the end
  71. *        of the string only if CHARS_ONLY is specified and if
  72. *        num_spaces is zero.  Otherwise NUL is put out as a
  73. *        printable character (blank).
  74. *
  75. * Returns    (None.    Function return type is void.)
  76. *
  77. * Version    3.0  (C)Copyright Blaise Computing Inc. 1986
  78. *
  79. **/
  80.  
  81. #include <string.h>
  82.  
  83. #include <bisr.h>
  84. #include <bquery.h>
  85. #include <bscreen.h>
  86.  
  87. #define  BEL      '\7'
  88. #define  BS      '\b'
  89. #define  CR      '\015'
  90. #define  LF      '\012'
  91.  
  92. void scwrstr(row,col,num_spaces,buffer,fore,back,option)
  93. int  row,col,num_spaces;
  94. char *buffer;
  95. int  fore,back,option;
  96. {
  97.     int  mode,columns,act_page,graphics;
  98.     char ch;
  99.     int  want_attr,oldmask,newmask,old_attr,new_attr;
  100.     int  save_row,save_col;
  101.     int  ax,bx,cx,dx,flags;          /* General registers          */
  102.     ADS  buffer_ads;
  103.     ALLREG allregs;
  104.     ADS  biosvec_ads;
  105.  
  106.     scmode(&mode,&columns,&act_page);
  107.     graphics  = (mode > 3 && mode != 7);
  108.     want_attr = ((option & CHAR_ATTR) != 0);
  109.  
  110.     utbound(row,0,scrows() - 1)       /* Force reasonable values      */
  111.     utbound(col,0,columns - 1)
  112.     if ((!want_attr) && num_spaces == 0)
  113.     num_spaces = (int) strlen(buffer);
  114.  
  115.     if (option & NO_MOVE_CUR)
  116.     {
  117.     sccurpos(&save_row,&save_col);/* Previous cursor location.    */
  118.     }
  119.     else
  120.     {
  121.     save_row = row;           /* Beginning of string.          */
  122.     save_col = col;
  123.     }
  124.  
  125.     if (fore == -1)              /* "oldmask" will help us       */
  126.     oldmask  = 0x0f;          /* extract the portion(s) of    */
  127.     else                  /* the previous attributes      */
  128.     oldmask  = 0x00;          /* which must be preserved.     */
  129.     if (back == -1)
  130.     oldmask |= 0xf0;
  131.  
  132.     /* BIOS video function 19 (decimal) is the fastest portable way   */
  133.     /* to write the string, but it has several limitations:          */
  134.     /*     (1) it can't preserve existing attributes, which must be     */
  135.     /*         done if screen is in text mode and either fore or back   */
  136.     /*         equals -1;                           */
  137.     /*     (2) it isn't present on the PC or PC-XT (unless an Enhanced  */
  138.     /*         Graphics Adapter is installed) or PCjr;              */
  139.     /*     (3) it assumes that the display page (as specified in BH) is */
  140.     /*         the active page.                          */
  141.  
  142.     scequip();
  143.  
  144.     if ((oldmask == 0x00             /* Ignoring prev. attr.  */
  145.          || graphics)             /* Graphics mode--don't  */
  146.                          /*  bother preserving    */
  147.                          /*  attributes          */
  148.         && (    b_pcmodel == IBM_AT      /* Have video function 19*/
  149.          || b_pcmodel == IBM_CV      /* Have video function 19*/
  150.          || b_ega     != ABSENT)     /* Have video function 19*/
  151.         && b_curpage == act_page)         /* This is active page   */
  152.  
  153.     {              /* Then BIOS video function 19 will do the job. */
  154.  
  155.     isretvec(16,&biosvec_ads);    /* Get address of BIOS video    */
  156.                       /* services.              */
  157.  
  158.     allregs.ax.hl.h = 19;
  159.     allregs.ax.hl.l = (unsigned char) (option & (CUR_AFTER | CHAR_ATTR));
  160.     allregs.bx.hl.h = (unsigned char) b_curpage;
  161.     allregs.bx.hl.l = (unsigned char) utnybbyt(back,fore);
  162.     allregs.cx.x    = num_spaces;
  163.     allregs.dx.x    = utbyword(row,col);
  164.     utabsptr(buffer,&buffer_ads);
  165.     allregs.bp    = buffer_ads.r;
  166.     allregs.es    = buffer_ads.s;
  167.     allregs.flags    = DEF_FLAGS;
  168.     iscalint(&biosvec_ads,          /* Call BIOS by simulating a    */
  169.          &allregs);          /* software interrupt.          */
  170.     }
  171.     else
  172.     {
  173.     sccurset(row,col);
  174.  
  175.     newmask = 0xff & ~oldmask;    /* "newmask" will help us       */
  176.                       /* extract the relevant          */
  177.                       /* portion(s) of the new          */
  178.                       /* attributes              */
  179.  
  180.     new_attr = utnybbyt(back,fore) & newmask;
  181.     if (oldmask == 0x00)
  182.         old_attr = 0;
  183.     if (fore == -1 || !want_attr)
  184.         fore = 1;
  185.     bx     = utbyword(b_curpage,0);
  186.     cx     = 1;
  187.     while (num_spaces--)
  188.     {
  189.         if ((ch = *buffer++) != CR
  190.                && ch != LF
  191.                && ch != BEL
  192.                && ch != BS
  193.                && (!graphics)
  194.                && oldmask != 0xff)
  195.         {
  196.                       /* Write character and          */
  197.                       /* attributes              */
  198.         if (oldmask != 0x00)
  199.         {              /* Retrieve previous attributes */
  200.             ax = utbyword(8,0);
  201.             bios(16,&ax,&bx,&cx,&dx,&flags);
  202.             old_attr = uthibyte(ax) & oldmask;
  203.         }
  204.                       /* Now old_attr holds the       */
  205.                       /* portion of the previous      */
  206.                       /* attributes which we must     */
  207.                       /* preserve.              */
  208.  
  209.         ax = utbyword(9,ch);        /* Write char & attribute */
  210.  
  211.         if (want_attr)
  212.             bx=utbyword(b_curpage,old_attr|((int)*buffer++&newmask));
  213.         else
  214.             bx=utbyword(b_curpage,old_attr|new_attr);
  215.  
  216.         bios(16,&ax,&bx,&cx,&dx,&flags);
  217.         }
  218.         else
  219.         if (want_attr)          /* We won't use attribute, so   */
  220.             buffer++;          /* step past it.              */
  221.  
  222.         scttywrt(ch,fore);          /* Handle cursor movement and   */
  223.                       /*   special characters.          */
  224.                       /* (Color is ignored since this */
  225.                       /*   is not graphics mode)      */
  226.     }
  227.     }
  228.  
  229.     if ((option & NO_MOVE_CUR) || !(option & CUR_AFTER))
  230.     sccurset(save_row,save_col);  /* Restore cursor position      */
  231.                       /* (either to previous location */
  232.                       /* or to beginning of string).  */
  233. }
  234.