home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / KEYWATCH.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  139 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /* keywatch.c 12-29-91 Robert Mashlan, Public Domain                *\
  4.  
  5.    DOS compiler portability modifications added by Bob Stout,
  6.    1:106/2000.6
  7.  
  8.    This program monitors the keyboard interrupt, and stores the
  9.    status of each key as to whether it is pressed or released.
  10.  
  11.    This is done by capturing interrupt 9, and watching the make/break
  12.    codes.  The status is updated in the keys array, where 1 means
  13.    that the key is pressed, while 0 means the key is released.  The
  14.    key array is uses the scan code for an index instead of the ascii
  15.    character.  It is simple enough to find the scan code for a key,
  16.    just run this program and watch the display.
  17.  
  18.    The ekeys array will reflect the status of keys found on an AT
  19.    keyboard.  For instance, the left and right alt keys are
  20.    differentiated, as well as the edit control keys on the numeric
  21.    keypad and the one not on the numeric keypad.
  22.  
  23.    Since this program installs an interrupt handler, it should be
  24.    terminated normally, such the keyboard handler can be removed.
  25.    The ^C/^Break exit is captured via signal(), but all possible
  26.    exits should be trapped.
  27.  
  28. \*                                                                  */
  29.  
  30. #include <stdio.h>
  31. #include <dos.h>
  32. #include <conio.h>
  33. #include <signal.h>
  34. #include "sniptype.h"
  35. #include "pchwio.h"
  36.  
  37. volatile char keys[128];           /* array of key states           */
  38. volatile char ekeys[128];          /* array of AT key states        */
  39.  
  40. #define KEYPORT        0x60        /* keyboard scan code port       */
  41. #define keyport()      inp(KEYPORT)
  42.         /* macro that returns the scancode of the key that caused   */
  43.         /* the interrupt                                            */
  44.  
  45. /* Define:                                                          *\
  46.  
  47.    installisr()
  48.          installation macro, installs newkbisr() in the keyboard
  49.          interrupt chain
  50.  
  51.    removeisr()
  52.          removal macro, call to remove newkbisr() from interrupt
  53.          chain.  oldkbisr()  must be removed before program ends
  54. \*                                                                  */
  55.  
  56. #ifdef __ZTC__
  57.  #define installisr() int_intercept(0x09, newkbisr, 0)
  58.  #define removeisr()  int_restore(0x09);
  59. #else
  60.  #define installisr()  (oldkbisr=getvect(0x09),setvect(0x09,newkbisr))
  61.  #define removeisr()   setvect(0x09,oldkbisr)
  62.  #ifdef __TURBOC__
  63.   void INTERRUPT (FAR *oldkbisr)(void);    /* address of old ISR   */
  64.  #else
  65.   void (INTERRUPT FAR *oldkbisr)(void);    /* address of old ISR   */
  66.  #endif
  67. #endif
  68.  
  69. #if defined(__ZTC__)
  70.  int newkbisr(struct INT_DATA *pd)
  71. #elif defined(__TURBOC__)
  72.  void INTERRUPT newkbisr(void)
  73. #else
  74.  void INTERRUPT FAR newkbisr(void)
  75. #endif
  76. {
  77.       static extkey;
  78.       BYTE scancode = (BYTE)keyport();         /* read keyboard scan code */
  79.  
  80.       if (scancode == 0xe0)
  81.             extkey = 1;               /* use ekey array on next scan code */
  82.       else
  83.       {
  84.             if (scancode & 0x80)                          /* key released */
  85.                   (extkey ? ekeys : keys)[scancode & 0x7f] = 0;
  86.             else  (extkey ? ekeys : keys)[scancode] = 1;
  87.             extkey = 0;
  88.       }
  89.  
  90. #ifdef __ZTC__
  91.       return 0;                         /* chain to previous keyboard ISR */
  92. #else
  93.       oldkbisr();                       /* chain to previous keyboard ISR */
  94. #endif
  95. }
  96.  
  97. int keyspressed(void)           /* returns number of keys being held down */
  98. {
  99.       int i, result = 0;
  100.  
  101.       for (i = 0; i < 128; i++)
  102.       {
  103.             result += keys[i];
  104.             result += ekeys[i];
  105.       }
  106.       return result;
  107. }
  108.  
  109. int main(void)
  110. {
  111.       int lastkeycount = 0;
  112.  
  113.       signal(SIGINT,SIG_IGN);  /* ignore ^C and ^Break */
  114.       installisr();            /* install interrupt handler */
  115.       while(1)
  116.       {
  117.             int i;
  118.  
  119.             if (keyspressed() != lastkeycount) /* change in keystatus */
  120.             {
  121.                   lastkeycount = keyspressed();
  122.                   puts("---");
  123.                   for(i = 0; i < 128; i++)
  124.                   {
  125.                         if (keys[i])
  126.                               printf("key with scan code %02x "
  127.                                     "has been pressed\n", i);
  128.                         if (ekeys[i])
  129.                               printf("key with scan codes e0 %02x "
  130.                                     "had been pressed\n", i);
  131.                   }
  132.             }
  133.             if (kbhit() && getch()==0x1b) /* terminate when Esc pressed */
  134.                   break;
  135.       }
  136.       removeisr();   /* remove interrupt handler */
  137.       return 0;
  138. }
  139.