home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / pmp016.zip / pmpdll.c < prev    next >
C/C++ Source or Header  |  1998-01-13  |  5KB  |  144 lines

  1. /* PMPAUSEDLL -- monitors keyboard/mouse usage
  2.  *
  3.  * This module is part of PM Pause, see pmpause.c for details.
  4.  *
  5.  * Written by Ewen McNeill <ewen@naos.co.nz>, Dec 1997.
  6.  * Copyright Ewen McNeill, 1997.
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  *---------------------------------------------------------------------------
  23.  * The structure is based loosely on xraydll (from EDM vol 5, issue 1),
  24.  * see http://www.edm2.com/ for more details.
  25.  *
  26.  * WARNING: there _is_ a race condition here with the update/clear of the
  27.  * count, in that it may be updated by different threads in parallel, and
  28.  * the exact result of doing so may be undefined.  However, the instructions
  29.  * used should, where possible, compile into a single machine code instruction
  30.  * and thus on a single processor be atomic. Where this doesn't happen, the
  31.  * overlapped instructions could result in the wrong count, but if the count
  32.  * is too high that is not a big problem (only want to tell something from
  33.  * nothing), and if it is too low, it'll be bumped up by the next action.
  34.  *
  35.  * We don't care too much about the margins, so it's faster to leave the
  36.  * race condition than bother with locks around it.  If necessary some
  37.  * locking could be added.
  38.  *---------------------------------------------------------------------------
  39.  * $Id: pmpdll.c 0.6 1998/01/13 02:18:32 ewen Exp $
  40.  */
  41.  
  42. /* OS/2 Header portions required */
  43. #define INCL_WIN
  44. #define INCL_DOSMODULEMGR
  45. #include <os2.h>
  46.  
  47. #include "pmpause.h"
  48.  
  49. static BOOL Hooked    = FALSE;      /* flag set when hooks are enabled      */
  50. static HMODULE hmDll  = NULLHANDLE; /* Handle to our own module (DLL)       */
  51. static HAB  habClient = NULLHANDLE; /* Handle to client anchor block        */
  52. static unsigned long keymouse = 0;  /* Number of keyboard/mouse messsages   */
  53.                                     /* since last cleared                   */
  54.  
  55. /*#define TESTHOOK*/                /* If TESTHOOK is defined we hook only  */
  56.                                     /* our process; otherwise system wide   */
  57. #ifdef TESTHOOK
  58.   HMQ hmqType = HMQ_CURRENT;        /* HMQ_CURRENT ==> current thread only  */
  59. #else
  60.   HMQ hmqType = NULLHANDLE;         /* NULLHANDLE  ==> system wide          */
  61. #endif
  62.  
  63. #define JUST_CLICKS                 /* If defined, only count mouse button  */
  64.                                     /* clicks (up/down), not movements      */
  65.  
  66. /* Hook for Input queue (for posted messages).
  67.  *
  68.  * We simply count the number of WM_CHAR, and WM_MOUSEMOVE messages that we
  69.  * see.  There will be at least two WM_CHAR messages for each keypress
  70.  * (up/down), and several WM_MOUSEMOVE messages for each mouse action, but
  71.  * we don't care -- we are only trying to distinguish "something" from
  72.  * "nothing".
  73.  *
  74.  * We always return FALSE (ie, continue processing) since we don't want to
  75.  * intercept the message, just note its passing.
  76.  */
  77. BOOL EXPENTRY PMPauseInputHook(HAB hab, PQMSG pQmsg, USHORT fs)
  78. {
  79.   switch(pQmsg->msg)
  80.   {
  81. #ifdef JUST_CLICKS
  82.     case WM_BUTTON1DOWN:           /* Just count button clicks, rest is idle */
  83.     case WM_BUTTON1UP:
  84.     case WM_BUTTON2DOWN:
  85.     case WM_BUTTON2UP:
  86.     case WM_BUTTON3DOWN:
  87.     case WM_BUTTON3UP:
  88. #else    
  89.     case WM_MOUSEMOVE:             /* Count all mouse movement; note this    */
  90. #endif                             /* will catch program simulated movement  */
  91.     case WM_CHAR:
  92.       keymouse++;                  /* Mouse and keyboard -- count 'em        */
  93.       break;
  94.  
  95.     default:                       /* Ignore the rest, we don't need 'em     */
  96.       break;
  97.   }
  98.  
  99.   return(FALSE);                   /* Keep processing the messages           */
  100. }
  101.  
  102. /* Return count of key/mouse actions since last cleared                      */
  103. unsigned long EXPENTRY EXPORT PMPauseGetCount(void)
  104. {
  105.   return keymouse;
  106. }
  107.  
  108. /* Clear count of key/mouse actions                                          */
  109. void EXPENTRY EXPORT PMPauseClearCount(void)
  110. {
  111.   keymouse = 0;
  112. }
  113.  
  114. /* Initialisation -- hook the queue that we want.                            */
  115. BOOL EXPENTRY EXPORT PMPauseInit(HWND window)
  116. {
  117.   if(! Hooked)
  118.   {
  119.     if(DosQueryModuleHandle(DLLNAME, &hmDll))
  120.       return FALSE;
  121.       
  122.     habClient = WinQueryAnchorBlock(window);
  123.     
  124.     WinSetHook(habClient, hmqType, HK_INPUT, (PFN)PMPauseInputHook, hmDll);
  125.  
  126.     Hooked = TRUE;
  127.   }
  128.   
  129.   return TRUE;
  130. }
  131.  
  132. /* Disable hooks again                                                      */
  133. BOOL EXPENTRY EXPORT PMPauseKill(void)
  134. {
  135.   if(Hooked)
  136.   {
  137.     WinReleaseHook(habClient, hmqType, HK_INPUT, (PFN)PMPauseInputHook, hmDll);
  138.  
  139.     Hooked = FALSE;
  140.   }
  141.  
  142.   return TRUE;        
  143. }
  144.