home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c005 / 4.ddi / C / SCTTYWIN.C < prev    next >
Encoding:
Text File  |  1987-04-13  |  7.8 KB  |  252 lines

  1. /**
  2. *
  3. * Name        scttywin -- Write a character to a rectangular region
  4. *                on the current display page via BIOS,
  5. *                TTY-style.
  6. *
  7. * Synopsis    scttywin(u_row,u_col,l_row,l_col,
  8. *              ch,fore,back,scr_fore,scr_back);
  9. *
  10. *        int  u_row    Top row of region (0 = top of screen)
  11. *        int  u_col    Leftmost column of region (0 = left edge)
  12. *        int  l_row    Bottom row of region
  13. *        int  l_col    Rightmost column of region
  14. *        char ch     Character to write
  15. *        int  fore    -1 if existing foreground is to be
  16. *                preserved; a value between 0 and 15
  17. *                specifies a new foreground attribute.
  18. *        int  back    -1 if existing background is to be
  19. *                preserved; a value between 0 and 15
  20. *                specifies a new background attribute.
  21. *        int  scr_fore    Foreground attribute of blank lines
  22. *                added when scrolling (-1 to use
  23. *                foreground attribute of character
  24. *                position before scroll).
  25. *        int  scr_back    Background attribute of blank lines
  26. *                added when scrolling (-1 to use
  27. *                background attribute of character
  28. *                position before scroll).
  29. *
  30. * Description    This function writes a character to a rectangular region
  31. *        on the current display page in the manner of a teletype.
  32. *        It treats carriage return, line feed, backspace, and
  33. *        bell as commands rather than as printable characters.
  34. *        All output and scrolling are confined to the region.
  35. *
  36. *        If the cursor is currently within the region, the
  37. *        character is written at that point.  If the cursor is
  38. *        not within the region, the character is written at the
  39. *        upper left corner of the region.  The cursor is left
  40. *        after the displayed character.
  41. *
  42. *        If the screen is in a text mode, specifying -1 for fore
  43. *        or back preserves the existing foreground or background
  44. *        attributes, respectively.  This will occur regardless of
  45. *        the value of option.  If the screen is in a graphics
  46. *        mode, then specifying -1 for fore will cause color 1 to
  47. *        be used.
  48. *
  49. *        The region is scrolled if a line feed occurs on the last
  50. *        row of the region or if the last row is overflowed.
  51. *
  52. *        If the screen is scrolled in text mode due to a line
  53. *        feed character and scr_fore or scr_back is -1, then the
  54. *        foreground or background attribute(s) (respectively) for
  55. *        the new blank row are taken from the character position
  56. *        last occupied before the scroll.  If the scroll is
  57. *        caused by overflowing the last row of the region and
  58. *        scr_fore or scr_back is -1, the respective attribute(s)
  59. *        are taken from the former attribute at the leftmost
  60. *        column of the bottom row.  Otherwise the value of
  61. *        scr_fore or scr_back is used.  (When scr_fore and
  62. *        scr_back are both -1, this uses the same convention as
  63. *        SCTTYWRT.)
  64. *
  65. *        If the screen is scrolled in a graphics mode, the
  66. *        scrolled text is given the color specified by scr_fore,
  67. *        unless scr_fore is -1, in which case color 1 is used.
  68. *
  69. * Example    This statement:
  70. *
  71. *            scttywrt(ch,fore);
  72. *
  73. *        is equivalent to the following in text modes:
  74. *
  75. *            scttywin(0,0,PC_BIG_ROWS,PC_COLS,
  76. *                 ch,-1,-1,-1,-1);
  77. *
  78. *        and to the following in graphics modes:
  79. *
  80. *            scttywin(0,0,PC_BIG_ROWS,PC_COLS,
  81. *                 ch,fore,-1,fore,-1);
  82. *
  83. *        provided that fore is not -1.
  84. *
  85. * Special    Tab characters ('\t') are displayed literally.
  86. * characters
  87. *        NUL ('\0') is a printable character (printed as a blank
  88. *        space).
  89. *
  90. *        Line feed ('\12') causes the cursor to move down one
  91. *        row, unless it is already on the bottom row of the
  92. *        region, in which case the screen is scrolled.
  93. *
  94. *        Carriage return ('\r') causes the cursor to move to the
  95. *        leftmost column of the region.
  96. *
  97. *        Backspace ('\b') causes the cursor to move one column to
  98. *        the left (non-destructively), unless it is already at
  99. *        the leftmost column of the region, in which case nothing
  100. *        happens.
  101. *
  102. *        The BEL character ('\7') causes the computer's bell to
  103. *        sound if the current page is active.
  104. *
  105. * Returns    (None.    Function return type is void.)
  106. *
  107. * Version    3.0  (C)Copyright Blaise Computing Inc. 1986
  108. *
  109. * Version    3.02 March 20, 1987
  110. *        Corrected cx value (character count) used in first call
  111. *            to BIOS.
  112. *
  113. **/
  114.  
  115. #include <bgenvid.h>              /* This routine doesn't care    */
  116.                       /* whether direct or BIOS       */
  117.                       /* version of BGENVID.H is used.*/
  118. #include <bscreen.h>
  119.  
  120. #define  BEL     '\7'
  121. #define  BS     '\b'
  122. #define  CR     '\r'
  123. #define  LF     '\12'
  124.  
  125. void scttywin(u_row,u_col,l_row,l_col,ch,fore,back,scr_fore,scr_back)
  126. int  u_row,u_col,l_row,l_col;
  127. char ch;
  128. int  fore,back,scr_fore,scr_back;
  129. {
  130.     int  mode,columns,act_page,last_row,graphics;
  131.     int  oldmask,old_attr;
  132.     int  ax,bx,cx,dx,flags;          /* General registers          */
  133.     int  row,col;
  134.  
  135.     scmode(&mode,&columns,&act_page);
  136.     last_row = scrows() - 1;
  137.     graphics = (mode > 3 && mode != 7);
  138.  
  139.     utbound(u_row,0,last_row)          /* Force reasonable values      */
  140.     utbound(u_col,0,columns - 1)
  141.     utbound(l_row,u_row,last_row)
  142.     utbound(l_col,u_col,columns - 1)
  143.  
  144.     sccurpos(&row,&col);
  145.     if (utrange(row,u_row,l_row) || utrange(col,u_col,l_col))
  146.     sccurset((row = u_row),(col = u_col));
  147.  
  148.     switch (ch)
  149.     {
  150.     case BEL:
  151.         scttywrt(ch,0);
  152.         break;              /* Don't beep on nonactive page */
  153.  
  154.     case BS:
  155.         if (col > u_col)          /* Don't back up past first     */
  156.         sccurset(row,col - 1);          /* column          */
  157.         break;
  158.  
  159.     case CR:
  160.         sccurset(row,u_col);      /* Beginning of current line    */
  161.         break;
  162.  
  163.     default:              /* First write the character    */
  164.         if (graphics)          /* Graphics mode:           */
  165.         {                  /* Ignore previous attributes   */
  166.         if (fore == -1)       /* since we can't read them.    */
  167.             fore = 1;
  168.         back     = 0;          /* Nonzero background causes    */
  169.                       /* trouble.              */
  170.         oldmask  = 0x00;      /* Ignore previous attributes.  */
  171.         }
  172.         else              /* Text mode:              */
  173.         {
  174.         if (fore == -1)       /* "oldmask" will help us       */
  175.             oldmask  = 0x0f;  /* extract the portion(s) of    */
  176.         else              /* the previous attributes      */
  177.             oldmask  = 0x00;  /* which must be preserved.     */
  178.         if (back == -1)
  179.             oldmask |= 0xf0;
  180.         }
  181.  
  182.         if (oldmask == 0xff)
  183.         {                  /* Write character only          */
  184.         ax = utbyword(10,ch);
  185.         bx = utbyword(b_curpage,0);
  186.         cx = 1;
  187.         bios(16,&ax,&bx,&cx,&dx,&flags);
  188.         }
  189.         else
  190.         {                  /* Write character with          */
  191.                       /* attributes              */
  192.         if (oldmask != 0x00)
  193.         {
  194.             ax = utbyword(8,0);
  195.             bx = utbyword(b_curpage,0);
  196.             bios(16,&ax,&bx,&cx,&dx,&flags);
  197.             old_attr = uthibyte(ax) & oldmask;
  198.         }
  199.         else
  200.             old_attr = 0;
  201.  
  202.         ax = utbyword(9,ch);
  203.         bx = utbyword(b_curpage,
  204.                   old_attr | (utnybbyt(back,fore) & ~oldmask));
  205.         cx = 1;
  206.         bios(16,&ax,&bx,&cx,&dx,&flags);
  207.         }
  208.  
  209.         ax = 0x0200;
  210.         bx = utbyword(b_curpage,0);
  211.         if (++col <= l_col)       /* Check for possible wrap      */
  212.         {                  /* This fits on current line    */
  213.         dx = utbyword(row,col);
  214.         bios(16,&ax,&bx,&cx,&dx,&flags);
  215.         break;
  216.         }
  217.                       /* Wrap to next line          */
  218.         dx = utbyword(row,col = u_col);
  219.         bios(16,&ax,&bx,&cx,&dx,&flags);
  220.     case LF:
  221.         if (row < l_row)
  222.         {                  /* No need to scroll          */
  223.         sccurset(row + 1,col);
  224.         break;
  225.         }
  226.                       /* Obtain attribute with which  */
  227.                       /* to fill new bottom line.     */
  228.         if (graphics)
  229.         {
  230.         if (scr_fore == -1)
  231.             scr_fore = 1;
  232.         }
  233.         else
  234.         {
  235.         scread(&fore,&back);      /* Obtain attribute from    */
  236.                       /* previous cursor position */
  237.         if (scr_fore == -1)
  238.             scr_fore = fore;
  239.         if (scr_back == -1)
  240.             scr_back = back;
  241.         }
  242.  
  243.                       /* Scroll up.              */
  244.         scpscrol(1,
  245.              utnybbyt(scr_back,scr_fore),
  246.              u_row,u_col,
  247.              l_row,l_col,
  248.              SCR_UP);
  249.         break;
  250.     }
  251. }
  252.