home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / KBQUERY.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  7.3 KB  |  257 lines

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