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

  1. /**
  2. *
  3. * Name        apquery -- Read response from CON: keyboard, echoing
  4. *               characters to the active page on the current
  5. *               display device.
  6. *
  7. * Synopsis    final = apquery(presp,resp_size,pscan,pnum_scrolled);
  8. *
  9. *        char final    Character that terminated input, or
  10. *                NUL ('\0') if an extended key
  11. *                sequence terminated the input.
  12. *        char *presp    Pointer to character buffer in which
  13. *                to return response.
  14. *        int  resp_size    Size of input buffer in bytes (including
  15. *                one byte for the trailing NUL ('\0')).
  16. *        int  *pscan    If the terminal character was an ASCII
  17. *                character, this is its value;
  18. *                if it was an extended key
  19. *                sequence, this is its scan code.
  20. *        int  *pnum_scrolled
  21. *                Number of lines the screen was scrolled.
  22. *
  23. * Description    This function returns a string of keystrokes from the
  24. *        user, echoing keystrokes and confining all I/O to the
  25. *        active page on the current display device.
  26. *
  27. *        The user may type characters as usual, terminating the
  28. *        input by one of the following:    ENTER, CTRL-M, CTRL-J,
  29. *        or a function key or other extended key sequence.  The
  30. *        characters are echoed and the cursor moves across the
  31. *        screen.  When the rightmost column of the screen is
  32. *        reached, the cursor moves to the next row, except that
  33. *        the screen is scrolled when the lower right corner of
  34. *        the screen is reached.    The input stops when the buffer
  35. *        is full.
  36. *
  37. *        Once the input buffer is full, the cursor remains just
  38. *        after the last response character.  Further keystrokes
  39. *        (except for backspace and terminating keys) cause beeps
  40. *        and are discarded.  Backspace works as usual.  The
  41. *        function does not return until ENTER or another
  42. *        terminating key has been pressed (even if the buffer is
  43. *        full).
  44. *
  45. *        The terminating character is not returned as part of the
  46. *        input.    If the terminating character is an ASCII
  47. *        character, its value is returned in *pscan and as the
  48. *        value of the function; if it was an extended key
  49. *        sequence, its scan code is returned in *pscan and the
  50. *        value of the function is zero.
  51. *
  52. * Special    The following keystrokes have special effects when
  53. * characters    entered as part of the response:
  54. *
  55. *        Backspace or CTRL-H ('\b') deletes the previous
  56. *        character entered and moves the cursor to that
  57. *        character's location.  A backspace at the beginning of
  58. *        the response has no effect.
  59. *
  60. *        ENTER or CTRL-M ('\15') terminates the response.
  61. *
  62. *        CTRL-J ('\12') terminates the response.
  63. *
  64. *        NULs (ASCII 0) are ignored and discarded.
  65. *
  66. *        TAB or CTRL-I ('\9') is echoed as one or more blank
  67. *        spaces as usual.  The TAB character is returned in the
  68. *        buffer.
  69. *
  70. *        CTRL-G causes a beep but is not returned as part of the
  71. *        response.
  72. *
  73. *        Special non-ASCII IBM keys (such as function keys and
  74. *        some ALT keys) terminate the response.
  75. *
  76. *        All other ASCII characters, including control
  77. *        characters, are echoed.  (Control characters are echoed
  78. *        as themselves, that is, without an uparrow ('^')
  79. *        prefix.)
  80. *
  81. * Returns    final        Character that terminated input, or
  82. *                NUL ('\0') if an extended key
  83. *                sequence terminated the input.
  84. *        *pscan        ASCII code or extended code of
  85. *                keystroke that terminated input.
  86. *        *presp        User's response as a string.
  87. *
  88. * Version    3.0 Copyright (C) Blaise Computing Inc. 1986
  89. *
  90. **/
  91.  
  92. #include <bapplic.h>
  93. #include <bkeybd.h>
  94. #include <bscreen.h>
  95.  
  96. #define  BEL         7          /* Bell       (CTRL-G)              */
  97. #define  BS         8          /* Backspace (CTRL-H)              */
  98. #define  TAB         9          /* Tab       (CTRL-I)              */
  99. #define  LF        10          /* Line feed (CTRL-J)              */
  100. #define  ENTER        13          /* ENTER or carriage return (CTRL-M)    */
  101. #define  CR        13
  102.  
  103. #define  TAB_WIDTH   8          /* Distance between tab stops (for      */
  104.                   /* echoing TAB characters)          */
  105.  
  106. char apquery(presp,resp_size,pscan,pnum_scrolled)
  107. char *presp;
  108. int  resp_size,*pscan,*pnum_scrolled;
  109. {
  110.     int  old_page,mode,columns,act_page;
  111.     char ch;
  112.     int  is_char;
  113.     int  row,col,begin_row,begin_col;
  114.     int  num_have = 0;
  115.     char *pbegin  = presp;
  116.     char *ptemp;
  117.  
  118.     old_page = b_curpage;          /* Save former display page.    */
  119.     scmode(&mode,&columns,&act_page);
  120.     scpage(act_page);              /* Direct I/O to active page.   */
  121.  
  122.     *pnum_scrolled =
  123.     num_have       = 0;
  124.     sccurpos(&begin_row,&begin_col);
  125.     row        = begin_row;
  126.     col        = begin_col;
  127.  
  128.     do                      /* Collect the response.          */
  129.     {
  130.                       /* Await a keystroke.          */
  131.     if (is_char = kbin(pscan))
  132.     {                  /* Got an ASCII character.      */
  133.  
  134.         switch (ch = (char) *pscan)
  135.         {
  136.         case LF:
  137.         case ENTER:
  138.             break;          /* This is a terminating          */
  139.                       /* character:  handle it at     */
  140.                       /* loop exit.              */
  141.  
  142.         case '\0':            /* Ignore NULs.                 */
  143.             break;
  144.  
  145.         case BEL:          /* BEL:  just beep.          */
  146.             scttywrt((char) BEL,1);
  147.             break;
  148.  
  149.         default:
  150.             if (num_have >= resp_size - 1)     /* Buffer full */
  151.             {
  152.             scttywrt((char) BEL,1);
  153.             }
  154.             else
  155.             {
  156.             do          /* Echo spaces or the char,     */
  157.             {          /* noting any scrolling.          */
  158.                 if (   col >= columns - 1
  159.                 && row >= scrows() - 1)
  160.                 ++*pnum_scrolled;
  161.                 scttywrt((ch == TAB ? (char) ' ' : ch),1);
  162.                 sccurpos(&row,&col);
  163.             } while (ch == TAB && (col % TAB_WIDTH));
  164.  
  165.                       /* Update response buffer.      */
  166.             num_have++;
  167.             *presp++ = ch;
  168.             }
  169.             break;
  170.  
  171.         case BS:
  172.             if (num_have)
  173.             {
  174.             num_have--;
  175.                       /* Move cursor to last char     */
  176.                       /* entered.              */
  177.             if (*--presp == TAB)
  178.             {          /* Delete TABs specially:       */
  179.                 *presp = '\0';
  180.                 row    = begin_row - *pnum_scrolled;
  181.                 col    = begin_col;
  182.                 ptemp  = pbegin;
  183.  
  184.                       /* Find new cursor location by  */
  185.                       /* walking forward through the  */
  186.                       /* response again.          */
  187.                 while ((ch = *ptemp++) != '\0')
  188.                 {
  189.                 do
  190.                 {
  191.                     if (++col > columns - 1)
  192.                     {
  193.                     row++;
  194.                     col = 0;
  195.                     }
  196.                 } while (ch == TAB && (col % TAB_WIDTH));
  197.                 }
  198.                 sccurset(row,col);
  199.                       /* Don't need to erase with a   */
  200.                       /* blank since the TAB was      */
  201.                       /* already displayed using      */
  202.                       /* blanks.              */
  203.  
  204.                       /* ("row" may be negative here  */
  205.                       /* if begin_row was scrolled    */
  206.                       /* off the screen, but that     */
  207.                       /* can only happen if user      */
  208.                       /* fills the screen with input.)*/
  209.             }
  210.             else
  211.             {          /* Just delete a normal          */
  212.                       /* character.              */
  213.  
  214.                 if (col)      /* Back up one column.      */
  215.                 sccurset(row,--col);
  216.                 else      /* Back up to previous row. */
  217.                 sccurset(--row,col = columns - 1);
  218.  
  219.                       /* Erase previous character.*/
  220.                 scwrite((char) ' ',1);
  221.             }
  222.             }
  223.             else
  224.             {
  225.             /* Do nothing */    /* Can't delete past  */
  226.             }                /* beginning.          */
  227.  
  228.             break;
  229.         }
  230.     }
  231.  
  232.     /* Note:  at this point, row and col indicate the next          */
  233.     /* position on the screen.                      */
  234.  
  235.     } while (is_char && (ch != ENTER) && (ch != LF));
  236.  
  237.     *presp = '\0';                    /* Terminate response string.   */
  238.  
  239.     scttywrt((char) CR,1);          /* Perform a final newline.     */
  240.     scttywrt((char) LF,1);
  241.     if (row >= scrows() - 1)
  242.     ++*pnum_scrolled;
  243.  
  244.     scpage(old_page);              /* Restore current display page */
  245.  
  246.     return is_char ? ch : (char) '\0';/* Successful exit.             */
  247. }
  248.