home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / c / pcw_c.zip / KEYBD.C < prev    next >
C/C++ Source or Header  |  1991-12-21  |  10KB  |  267 lines

  1. /**********************************************************/
  2. /* File Id.                  Keybd.C                      */
  3. /* Author.                   Stan Milam.                  */
  4. /* Date Written.             03/08/89.                    */
  5. /*                                                        */
  6. /*          (c) Copyright 1989-90 by Stan Milam           */
  7. /*                                                        */
  8. /* Comments:  This file contains functions to querry the  */
  9. /* keyboard to see if characters are waiting and to read  */
  10. /* the characters from the keyboard.                      */
  11. /* Updated 12 Aug. 91 to simplify the keyboard code and   */
  12. /* and give new abilities.  keyin() and readkey() now make*/
  13. /* calls to an internal routine, _getkey().               */
  14. /*                                                        */
  15. /**********************************************************/
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include <dos.h>
  21. #include <io.h>
  22. #include "pcw.i"
  23. #include "pcwproto.h"
  24. #include "keys.h"
  25. #ifdef MSC
  26. #   include <stdlib.h>
  27. #   include <bios.h>
  28. #endif
  29.  
  30. static union REGS regs;
  31.  
  32. /***************************************************************/
  33. /*                    stdin_is_redirected()                    */
  34. /*                                                             */
  35. /* ADDED 15 DEC. 91.                                           */
  36. /* This function is used to determine if stdin is redirected or*/
  37. /* not.  It looks at the first file handle entry in the PSP to */
  38. /* see if it pointing to the console device (value 1).  If is  */
  39. /* not standard input is being directed.  We do this this way  */
  40. /* because calling isatty() will cause Cntl-C/Break to be a    */
  41. /* problem when stdin is not redirected.                       */
  42. /*                                                             */
  43. /***************************************************************/
  44.  
  45. static int stdin_is_redirected ( void ) {
  46.  
  47.     char far *fht;
  48.  
  49.     fht = MK_FP( _psp, 0x18 );
  50.     return ( fht[0] != 1 );
  51. }
  52.  
  53. /***************************************************************/
  54. /*                      __bios_keyboard()                      */
  55. /*                                                             */
  56. /* This function is used internally to generate interrupt calls*/
  57. /* to the BIOS keyboard code.  By doing things this way we can */
  58. /* get out of the way of Power C Trace when it is active and   */
  59. /* not lock up the keyboard. Added this routine 12 Aug. 91.    */
  60. /*                                                             */
  61. /***************************************************************/
  62.  
  63. static void __bios_keyboard( void ) {
  64.  
  65. #ifdef __POWERC
  66.     crt_lock();
  67. #endif
  68.  
  69.     int86(0x16, ®s, ®s);
  70.  
  71. #ifdef __POWERC
  72.     crt_unlock();
  73. #endif
  74. }
  75.  
  76. /**********************************************************/
  77. /*                         Isxkeybd                       */
  78. /*                                                        */
  79. /* This function will tell us if the keyboard is an en-   */
  80. /* hanced keyboard or not.                                */
  81. /**********************************************************/
  82.  
  83. int isxkeybd(void) {
  84.  
  85.    memset(®s, '\0', sizeof(union REGS));
  86.    regs.h.ah = 0x11;
  87.    __bios_keyboard();
  88.    if (regs.h.ah == 0x11) return(0);
  89.    return(1);
  90. }
  91.  
  92. /**********************************************************/
  93. /*                        Keypressed                      */
  94. /*                                                        */
  95. /* This function will determine if a character is waiting */
  96. /* in the keyboard buffer. Returns 1 if there is and 0 if */
  97. /* one is not.                                            */
  98. /*                                                        */
  99. /* Rewrote function 15 Dec 91.  Now reports if input is   *
  100. /* from stdin rather than keyboard if stdin is redirected.*/
  101. /* Also reports if a MOUSE key has been pressed.  The ret-*/
  102. /* urn values are as follows.                             */
  103. /*   STDIN redirected = 1                                 */
  104. /*   Normal Keyboard  = 2                                 */
  105. /*   Mouse Key Pressed= 3                                 */
  106. /**********************************************************/
  107.  
  108. int keypressed(void) {
  109.  
  110.     if ( stdin_is_redirected() )       /* Is stdin redirected ?   */
  111.          if ( !feof( stdin ) )         /* If it is, is it at EOF? */
  112.               return 1;                /* If Not EOF return input ready */
  113.  
  114. #ifdef MSC
  115.     regs.x.ax = _bios_keybrd(_KEYBRD_READY);
  116. #else
  117.     memset(®s, '\0', sizeof(union REGS));
  118.     regs.h.ah = 1;
  119.     __bios_keyboard();
  120.     if ((regs.x.flags & 0x0040) == 0x40) regs.x.ax = 0;
  121. #endif
  122.     if ( regs.x.ax ) return 2;
  123.  
  124.     if ( mpresent ) {
  125.          if ( get_mpressed( RITEM ) || get_mpressed( LEFTM ) ) {
  126.               return 3;
  127.          }
  128.     }
  129.  
  130.    /* If nothing from stdin, keyboard or mouse return zero */
  131.  
  132.    return 0;
  133. }
  134.  
  135. /***************************************************************/
  136. /*                         getkey()                            */
  137. /*                                                             */
  138. /* This function added 12 Aug. 91 as a replacement for read-   */
  139. /* key() and keyin().                                          */
  140. /*                                                             */
  141. /* Rewrote 15 Dec. 91 to call keypressed(). Uses return value  */
  142. /* from keypressed to (1) read from STDIN, (2) read from key-  */
  143. /* board using BIOS call, and (3) read from MOUSE.             */
  144. /*                                                             */
  145. /***************************************************************/
  146.  
  147. static int _getkey( void ) {
  148.  
  149.     int ch;
  150.     int mrow, mcol, mstat;
  151.  
  152.     while ( 1 ) {
  153.         switch ( keypressed() ) {
  154.             case 0 : continue;
  155.             case 1 :
  156.                ch = getc( stdin );
  157.                if ( ch == 0 ) {
  158.                     ch = ( getc( stdin ) ) << 8;
  159.                }
  160.                return ch;
  161.             case 2 :
  162.                memset(®s, 0, sizeof(regs));
  163.                __bios_keyboard();
  164.                  if (regs.h.al == 0) ch = regs.x.ax;
  165.                else ch = (regs.x.ax & 0x00ff);
  166.                if (ch == CR) ch = ENTER;
  167.                return ch;
  168.             case 3 :
  169.                get_mpos( &mrow, &mcol, &mstat );
  170.                switch ( mstat ) {
  171.                    case 1 : return LEFT_MOUSE_KEY;
  172.                    case 2 : return RITE_MOUSE_KEY;
  173.                    case 3 : return BOTH_MOUSE_KEY;
  174.                }
  175.                break;
  176.         }
  177.     }
  178.     return 0;                          /* Should never reach here */
  179. }
  180.  
  181. /**********************************************************/
  182. /*                         ReadKey                        */
  183. /*                                                        */
  184. /* This function will read a character from the keyboard  */
  185. /* buffer.  If the key is a special key (function or      */
  186. /* arrow key) we will return 0 and not read the character.*/
  187. /* We will also set a static flag indicating the character*/
  188. /* is still waiting to be read and when read we will      */
  189. /* the scan code for the special key.                     */
  190. /**********************************************************/
  191.  
  192. int readkey(void) {
  193.  
  194.     return ( _getkey() );
  195. }
  196.  
  197. /**********************************************************/
  198. /*                           Keyin.C                      */
  199. /*                                                        */
  200. /* Comments: Used to read keyboard and handle special keys*/
  201. /**********************************************************/
  202.  
  203. int keyin(void) {
  204.  
  205.     return ( _getkey() );
  206. }
  207.  
  208. /**********************************************************/
  209. /*                       Keybrd_Flush                     */
  210. /*                                                        */
  211. /* Routine to flush the keyboard.                         */
  212. /**********************************************************/
  213.  
  214. void keybrd_flush(void) {
  215.  
  216.    while (keypressed()) _getkey();
  217. }
  218.  
  219. /**********************************************************/
  220. /*                          KeyWait                       */
  221. /*                                                        */
  222. /* Keywait will wait for specified number of seconds      */
  223. /* before returning control to caller.  If a key has been */
  224. /* pressed then return immediately.                       */
  225. /**********************************************************/
  226.  
  227. int keywait(int seconds) {
  228.  
  229.    int ticks, rc, ch;
  230.    int mrow, mcol, mstat;
  231.  
  232.    rc = -1;                            /* Defualt return value */
  233.    keybrd_flush();                     /* Flush out the keyboard */
  234.    ticks = seconds * 9;                /* Approximate number of clock ticks */
  235.    if (ticks < 0) ticks *= -1;         /* Make sure its positive */
  236.    while(ticks) {                      /* While count not zero */
  237.       if ((ch = keypressed())) {       /* Was a key pressed ? */
  238.          if ( ch == 3 ) {
  239.             get_mpos(&mrow,&mcol,&mstat);
  240.             switch ( mstat ) {
  241.                case 1 : return LEFT_MOUSE_KEY;
  242.                case 2 : return RITE_MOUSE_KEY;
  243.                case 3 : return BOTH_MOUSE_KEY;
  244.             }
  245.          }
  246.          rc = _getkey();               /* Return the key that was pressed */
  247.          keybrd_flush();               /* Flush the keyboard */
  248.          return(rc);                   /* Return immediately */
  249.       }
  250.       rest(1);                         /* Wait 1 clock tick */
  251.       ticks--;                         /* Decrement the count */
  252.    }
  253.    return(rc);
  254. }
  255.  
  256. /*
  257. int main ( void ) {
  258.  
  259.     int rv;
  260.  
  261.     for ( rv = _getkey(); rv != 27; rv = getkey() )
  262.         printf("%04x\n", rv);
  263.  
  264.     return ( 0 );
  265. }
  266. */
  267.