home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / IPCX.ZIP / MONITOR.C next >
C/C++ Source or Header  |  1989-09-20  |  4KB  |  160 lines

  1. /* monitor.c RHS 5/1/89
  2.  *
  3.  This program demonstrates the use of character device monitors on the
  4.  keyboard. It creates a keyboard monitor which you can run from any session
  5.  or the DETACHed session. Once you run the monitor with:
  6.  
  7.  MONITOR
  8.  
  9.  you can activate the monitor with Alt-F10. This will create a pop-up screen
  10.  which will wait for any key press to end.
  11.  
  12.  You can terminate the monitor with Ctrl-F10.
  13.  
  14.  */
  15.  
  16. #define INCL_DOS
  17. #define INCL_VIO
  18. #define INCL_KBD
  19. #define INCL_ERRORS
  20.  
  21. #include<os2.h>
  22. #include<mt\stdio.h>
  23. #include<mt\conio.h> 
  24. #include<mt\process.h>
  25.  
  26. unsigned long semhandle = 0L;
  27. unsigned char HotKey = 0x71;                /* HotKey = Alt-F10            */
  28. unsigned char TerminateKey = 0x67;        /* TerminateKey = Ctrl-F10    */
  29. unsigned program_active = TRUE;
  30. unsigned popup_active = FALSE;
  31.  
  32. MONIN monInbuf;
  33. MONOUT monOutbuf;
  34.  
  35. #define    THREADSTACK    400
  36. char monitor_stack[THREADSTACK];
  37.  
  38. #define MONINBUFSIZE (sizeof(monInbuf)-sizeof(monInbuf.cb))
  39. #define MONOUTBUFSIZE (sizeof(monOutbuf)-sizeof(monOutbuf.cb))
  40. #define RELEASE     0x40                        /* bit mask to distinguish    */
  41. #define MAXMILLISECONDS        20000L
  42. #define SLEEPTIME                1000L
  43.  
  44. typedef struct _keypacket                    /* KBD monitor data record */
  45.     {
  46.     unsigned       mnflags;
  47.     KBDKEYINFO       cp;
  48.     unsigned       ddflags;
  49.     } KEYBUFF;
  50.  
  51.  
  52. void error_exit(USHORT err, char *msg);
  53. void main(void);
  54. void keyboard_monitor(void);
  55.  
  56. void main(void)
  57.     {
  58.     USHORT popupwait = (VP_WAIT | VP_OPAQUE);
  59.     KBDKEYINFO kbdkeyinfo;
  60.     long milliseconds;
  61.  
  62.     DosSemSet(&semhandle);
  63.  
  64.     if(_beginthread(keyboard_monitor,monitor_stack,THREADSTACK,NULL) == -1)
  65.         error_exit(-1,"_beginthread");
  66.  
  67.     while(TRUE)
  68.         {
  69.         DosSemRequest(&semhandle,SEM_INDEFINITE_WAIT);    /* wait for semaphore*/
  70.  
  71.         if(!program_active)                                /* time to terminate?        */
  72.             break;                                            /* then get out                */
  73.         VioPopUp(&popupwait,0);
  74.         printf("You made it...press a key");
  75.  
  76.                                 /* wait 20 seconds for keystroke, then break out    */
  77.         for( milliseconds = 0L; milliseconds < MAXMILLISECONDS;
  78.                 milliseconds += SLEEPTIME)
  79.             {
  80.             KbdCharIn(&kbdkeyinfo,IO_NOWAIT,0);        /* check for key press        */
  81.             if(kbdkeyinfo.fbStatus & FINAL_CHAR_IN)/* if pressed, break out    */
  82.                 break;
  83.             DosSleep(SLEEPTIME);                            /* sleep for a while            */
  84.             }
  85.  
  86.         VioEndPopUp(0);                                    /* end the popup                */
  87.         popup_active = FALSE;
  88.         }
  89.     DosExit(EXIT_PROCESS,0);                            /* kill the process            */
  90.     }
  91.  
  92. void keyboard_monitor(void)
  93.     {
  94.     USHORT retval;
  95.     SEL gdt_descriptor, ldt_descriptor;   /* infoseg descriptors */
  96.     KEYBUFF keybuff;
  97.     unsigned count;
  98.     HKBD KBDHandle;
  99.     PGINFOSEG gdt;
  100.     PLINFOSEG ldt;
  101.  
  102.     monInbuf.cb = MONINBUFSIZE;
  103.     monOutbuf.cb = MONINBUFSIZE;
  104.  
  105.         /* obtain a handle for registering buffers */
  106.     if(retval = DosMonOpen ( "KBD$", &KBDHandle ))
  107.         error_exit(retval,"DosMonOpen");
  108.  
  109.     if(DosGetInfoSeg(&gdt_descriptor, &ldt_descriptor))
  110.         error_exit(retval,"DosGetInfoSeg");
  111.  
  112.     gdt = MAKEPGINFOSEG(gdt_descriptor);
  113.     ldt = MAKEPLINFOSEG(ldt_descriptor);
  114.  
  115.     /* register the buffers to be used for monitoring */
  116.     if(retval = DosMonReg ( KBDHandle, (PBYTE)&monInbuf, (PBYTE)&monOutbuf,
  117.             MONITOR_BEGIN, gdt->sgCurrent))
  118.         error_exit(retval,"DosMonReg");
  119.  
  120.                                                 /* raise thread priority    */
  121.     DosSetPrty(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
  122.  
  123.     for(keybuff.cp.chChar = 0; ; )                /* loop thru all keyboard in*/
  124.         {
  125.         count = sizeof(keybuff);
  126.                                                 /* read keyboard            */
  127.         if(retval = DosMonRead ((PBYTE)&monInbuf, IO_WAIT, (PBYTE)&keybuff, (PUSHORT)&count ))
  128.             error_exit(retval,"DosMonRead");
  129.                                                 /* if make on our key        */
  130.         if(keybuff.cp.chChar == 0)
  131.             if(!popup_active && (keybuff.cp.chScan == HotKey) &&
  132.                     !(keybuff.ddflags & RELEASE))
  133.                 {
  134.                 popup_active = TRUE;
  135.                 DosSemClear(&semhandle);
  136.                 continue;
  137.                 }
  138.             else if((keybuff.cp.chScan == TerminateKey) &&
  139.                     !(keybuff.ddflags & RELEASE))
  140.                 {
  141.                 program_active = FALSE;
  142.                 break;
  143.                 }
  144.  
  145.         if(retval = DosMonWrite((PBYTE)&monOutbuf,(PBYTE)&keybuff,count))
  146.             error_exit(retval,"DosMonWrite");
  147.         }
  148.     DosMonClose(KBDHandle);                                /* close the monitor            */
  149.     DosSemClear(&semhandle);
  150.     DosExit(EXIT_THREAD,0);                            /* kill the thread            */
  151.     }
  152.  
  153. void error_exit(USHORT err, char *msg)
  154.     {
  155.     printf("Error %u returned from %s\n",err,msg);
  156.     DosExit(EXIT_PROCESS,0);
  157.     }
  158.  
  159.  
  160.