home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / kwikstik.zip / STIKHOOK.C < prev    next >
C/C++ Source or Header  |  1994-03-25  |  12KB  |  274 lines

  1. /*
  2.  * stikhook.c
  3.  *
  4.  * This file contains the system input hook, and installation and
  5.  * deinstallation entry points.  This is turned into a DLL, since 
  6.  * system hooks must reside in a DLL.
  7.  *
  8.  * Written 900301 by John W. Cocula
  9.  */
  10.  
  11. #define INCL_DOSMODULEMGR
  12. #define INCL_DOSSEMAPHORES
  13. #define INCL_WINDIALOGS
  14. #define INCL_WINHOOKS
  15. #define INCL_WININPUT
  16. #define INCL_WINMESSAGEMGR
  17. #include <os2.h>
  18.  
  19. #include "main.h"
  20.  
  21. int _acrtused = 0;
  22.  
  23. BOOL    fAddingTwo = TRUE;
  24.  
  25.  
  26. #define MAXQMSGBUFFERSIZE       10
  27. static QMSG    qmsgBuffer      [MAXQMSGBUFFERSIZE];
  28. static ULONG   ulQmsgBottom    = 0;
  29. static ULONG   ulQmsgTop       = 0;
  30. static HMODULE hModule;
  31. static BOOL    bFirstTimePlaybackHook = TRUE;
  32.  
  33. static HMODULE hModule;
  34.  
  35. ULONG APIENTRY _export JPHook( HAB hab, BOOL fSkip, PQMSG lpqmsg );
  36.  
  37. BOOL APIENTRY _export StickyInputHook( HAB hab, PQMSG lpqmsg, USHORT fs )
  38. {
  39.    /*
  40.     * The lpqmsg parameter points to a queue-message structure.
  41.     * Returns FALSE to let the message through to rest of hook
  42.     * chain. Returns TRUE to prevent further message processing.
  43.     */
  44.  
  45.    if ((lpqmsg->msg == WM_CHAR)                    && 
  46.        (SHORT2FROMMP(lpqmsg->mp2) == VK_SHIFT)     &&
  47.        (SHORT1FROMMP(lpqmsg->mp1) & KC_VIRTUALKEY) &&
  48.        !(SHORT1FROMMP(lpqmsg->mp1) & KC_KEYUP))
  49.    {
  50.       if (fAddingTwo)
  51.       {
  52.          /* Deinstall the input hook. */
  53.  
  54.          if (!hModule)
  55.             DosGetModHandle( "STIKHOOK", &hModule );
  56.  
  57.          WinReleaseHook( hab, NULL, HK_INPUT, 
  58.                          StickyInputHook, hModule );
  59.  
  60.          /* JP hook is only going to do 4 messages. */
  61.  
  62.          qmsgBuffer[ulQmsgTop].hwnd = 0L;
  63.          qmsgBuffer[ulQmsgTop].msg  = WM_CHAR;
  64.          qmsgBuffer[ulQmsgTop].mp1  = 
  65.                    MPFROM2SHORT(SHORT1FROMMP(lpqmsg->mp1) & ~KC_KEYUP,
  66.                                 SHORT2FROMMP(lpqmsg->mp1));
  67.          qmsgBuffer[ulQmsgTop].mp2  = lpqmsg->mp2;
  68.          qmsgBuffer[ulQmsgTop].time = 300;
  69.          qmsgBuffer[ulQmsgTop].ptl  = lpqmsg->ptl;
  70.          ulQmsgTop++;
  71.  
  72.          qmsgBuffer[ulQmsgTop].hwnd = 0L;
  73.          qmsgBuffer[ulQmsgTop].msg  = WM_CHAR;
  74.          qmsgBuffer[ulQmsgTop].mp1  = lpqmsg->mp1;
  75.          qmsgBuffer[ulQmsgTop].mp2  = lpqmsg->mp2;
  76.          qmsgBuffer[ulQmsgTop].time = 300;
  77.          qmsgBuffer[ulQmsgTop].ptl  = lpqmsg->ptl;
  78.          ulQmsgTop++;
  79.  
  80.          qmsgBuffer[ulQmsgTop].hwnd = 0L;
  81.          qmsgBuffer[ulQmsgTop].msg  = WM_CHAR;
  82.          qmsgBuffer[ulQmsgTop].mp1  = 
  83.                    MPFROM2SHORT(SHORT1FROMMP(lpqmsg->mp1) & ~KC_KEYUP,
  84.                                 SHORT2FROMMP(lpqmsg->mp1));
  85.          qmsgBuffer[ulQmsgTop].mp2  = lpqmsg->mp2;
  86.          qmsgBuffer[ulQmsgTop].time = 300;
  87.          qmsgBuffer[ulQmsgTop].ptl  = lpqmsg->ptl;
  88.          ulQmsgTop++;
  89.  
  90.          qmsgBuffer[ulQmsgTop].hwnd = 0L;
  91.          qmsgBuffer[ulQmsgTop].msg  = WM_CHAR;
  92.          qmsgBuffer[ulQmsgTop].mp1  = lpqmsg->mp1;
  93.          qmsgBuffer[ulQmsgTop].mp2  = lpqmsg->mp2;
  94.          qmsgBuffer[ulQmsgTop].time = 300;
  95.          qmsgBuffer[ulQmsgTop].ptl  = lpqmsg->ptl;
  96.          ulQmsgTop++;
  97.  
  98.          /* Install the journal playback hook. */
  99.  
  100.          if (WinSetHook( hab, NULL, HK_JOURNALPLAYBACK, (PFN)&JPHook, hModule ))
  101.             WinAlarm( HWND_DESKTOP, WA_NOTE ); //!!!
  102.       }
  103.  
  104.       fAddingTwo = !fAddingTwo;
  105.  
  106.       return FALSE;
  107.    }
  108.  
  109.    return FALSE;
  110.  
  111. }  /* StickyInputHook */
  112.  
  113. ULONG APIENTRY _export JPHook( HAB hab, BOOL fSkip, PQMSG lpqmsg )
  114. {
  115.    static       QMSG            qmsgMouse;
  116.    static       QMSG            qmsgCurrent;
  117.    static       LONG            lLastMsgTime            = 0L;
  118.    static       LONG            lCurrentMsgTime         = 0L;
  119.    static       LONG            lMsgDelay               = 0L;
  120.    static       LONG            lDelayRemaining         = 0L;
  121.    static       LONG            lLastSequencedEventTime = 0L;
  122.                   
  123.                 /*------------------------------------------------------*/
  124.                 /* Store the passed time as the current message time    */
  125.                 /*------------------------------------------------------*/
  126.                         /*----------------------------------------------*/
  127.                         /* Note: if fSkip is TRUE, the lpqmsg pointer   */
  128.                         /*       will be NULL.                          */
  129.                         /*----------------------------------------------*/
  130.    if (lpqmsg) {
  131.       lCurrentMsgTime = lpqmsg->time;
  132.    }
  133.                 /*------------------------------------------------------*/
  134.                 /* The system requests that a NEW message be prepared   */
  135.                 /*------------------------------------------------------*/
  136.    if (fSkip) {
  137.                         /*----------------------------------------------*/
  138.                         /* No more messages on queue - release the hook */
  139.                         /*----------------------------------------------*/
  140.       if (ulQmsgBottom == ulQmsgTop) {
  141.          WinReleaseHook (
  142.                          hab,
  143.                          0L,
  144.                          HK_JOURNALPLAYBACK,
  145.                          (PFN) JPHook,
  146.                          hModule
  147.                         );
  148.                                 /*--------------------------------------*/
  149.                                 /* Set a mouse move "in place" message  */
  150.                                 /*--------------------------------------*/
  151.          qmsgCurrent = qmsgMouse;
  152. #if 0
  153.                                 /*--------------------------------------*/
  154.                                 /* Reinstall the input hook             */
  155.                                 /*--------------------------------------*/
  156.          WinSetHook (
  157.                      hab,
  158.                      0L,
  159.                      HK_INPUT,
  160.                      StickyInputHook,
  161.                      hModule
  162.                      );
  163. #endif
  164.       }
  165.                           
  166.                         /*----------------------------------------------*/
  167.                         /* Prepare and pass the next message            */
  168.                         /*----------------------------------------------*/
  169.       else {
  170.                                 /*--------------------------------------*/
  171.                                 /* Update the time of last message      */
  172.                                 /*--------------------------------------*/
  173.          lLastMsgTime = lLastSequencedEventTime;
  174.                                 /*--------------------------------------*/
  175.                                 /* Copy current message from the queue  */
  176.                                 /*--------------------------------------*/
  177.          qmsgCurrent = qmsgBuffer[ulQmsgBottom];
  178.                                 /*--------------------------------------*/
  179.                                 /* Update the current mouse position so */
  180.                                 /* that the mouse stays put when we     */
  181.                                 /* playback                             */
  182.                                 /*--------------------------------------*/
  183.          if (qmsgCurrent.msg == WM_MOUSEMOVE) {
  184.             qmsgMouse.mp1   = qmsgCurrent.mp1;
  185.             qmsgMouse.mp2   = qmsgCurrent.mp2;
  186.             qmsgMouse.ptl.x = qmsgCurrent.ptl.x;
  187.             qmsgMouse.ptl.y = qmsgCurrent.ptl.y;
  188.          }
  189.                                 /*--------------------------------------*/
  190.                                 /* Update (and wrap) the queue pointer  */
  191.                                 /*--------------------------------------*/
  192.          ulQmsgBottom++;
  193.          if (ulQmsgBottom >= MAXQMSGBUFFERSIZE) {
  194.             ulQmsgBottom=0L;
  195.          }
  196.                                 /*--------------------------------------*/
  197.                                 /* New message - so set up the delay    */
  198.                                 /*               timing variables       */
  199.                                 /*--------------------------------------*/
  200.          lMsgDelay               = qmsgCurrent.time;
  201.          lDelayRemaining         = lMsgDelay - (lCurrentMsgTime - lLastMsgTime);
  202.          if (lDelayRemaining < 0) {
  203.             lDelayRemaining  = 0L;
  204.          }
  205.          lLastSequencedEventTime = lCurrentMsgTime + lDelayRemaining;
  206.          qmsgCurrent.time        = lLastSequencedEventTime;
  207.       }
  208.    } 
  209.                 /*------------------------------------------------------*/
  210.                 /* The system requests a PEEK at the CURRENT message    */
  211.                 /*------------------------------------------------------*/
  212.    else {
  213.                         /*----------------------------------------------*/
  214.                         /* Initialize the variables on the first pass   */
  215.                         /*----------------------------------------------*/
  216.       if (bFirstTimePlaybackHook) {
  217.          bFirstTimePlaybackHook  = 0;
  218.          lLastMsgTime            = 0L;
  219.          lCurrentMsgTime         = 0L;
  220.          lMsgDelay               = 0L;
  221.          lDelayRemaining         = 0L;
  222.          lLastSequencedEventTime = 0L;
  223.                                 /*--------------------------------------*/
  224.                                 /* Initialize the default mouse move    */
  225.                                 /*--------------------------------------*/
  226.          qmsgMouse.hwnd  = HWND_DESKTOP;
  227.          qmsgMouse.msg   = WM_MOUSEMOVE;
  228.          qmsgMouse.mp1   = (MPARAM) 0;
  229.          qmsgMouse.mp2   = (MPARAM) 0;
  230.          qmsgMouse.time  = 0L;
  231.          qmsgMouse.ptl.x = 0L;
  232.          qmsgMouse.ptl.y = 0L;
  233.                                 /*--------------------------------------*/
  234.                                 /* Send the same message as before      */
  235.                                 /*--------------------------------------*/
  236.          if (ulQmsgBottom == ulQmsgTop) {
  237.             qmsgCurrent = qmsgMouse;
  238.          }
  239.                                 /*--------------------------------------*/
  240.                                 /* Use the next message in the queue    */
  241.                                 /*--------------------------------------*/
  242.          else {
  243.             qmsgCurrent = qmsgBuffer[ulQmsgBottom];
  244.                                         /*------------------------------*/
  245.                                         /* New message - so set up the  */
  246.                                         /*      delay timing variables  */
  247.                                         /*------------------------------*/
  248.             lMsgDelay               = qmsgCurrent.time;
  249.             lDelayRemaining         = lMsgDelay - (lCurrentMsgTime - lLastMsgTime);
  250.             if (lDelayRemaining < 0) {
  251.                lDelayRemaining  = 0L;
  252.             }
  253.             lLastSequencedEventTime = lCurrentMsgTime + lDelayRemaining;
  254.             qmsgCurrent.time        = lLastSequencedEventTime;
  255.          }
  256.       }
  257.                         /*----------------------------------------------*/
  258.                         /* Copy current message to the passed pointer   */
  259.                         /*----------------------------------------------*/
  260.       if (lpqmsg) {
  261.          *lpqmsg = qmsgCurrent;
  262.       }
  263.    }
  264.                 /*------------------------------------------------------*/
  265.                 /* Update & return the remaining delay for this message */
  266.                 /*------------------------------------------------------*/
  267.    lDelayRemaining = lMsgDelay - (lCurrentMsgTime - lLastMsgTime);
  268.    if (lDelayRemaining < 0 ) {
  269.       lDelayRemaining = 0L;
  270.    }
  271.    return ((ULONG)lDelayRemaining);
  272. }
  273.  
  274.