home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 8 Other
/
08-Other.zip
/
kwikstik.zip
/
STIKHOOK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-25
|
12KB
|
274 lines
/*
* stikhook.c
*
* This file contains the system input hook, and installation and
* deinstallation entry points. This is turned into a DLL, since
* system hooks must reside in a DLL.
*
* Written 900301 by John W. Cocula
*/
#define INCL_DOSMODULEMGR
#define INCL_DOSSEMAPHORES
#define INCL_WINDIALOGS
#define INCL_WINHOOKS
#define INCL_WININPUT
#define INCL_WINMESSAGEMGR
#include <os2.h>
#include "main.h"
int _acrtused = 0;
BOOL fAddingTwo = TRUE;
#define MAXQMSGBUFFERSIZE 10
static QMSG qmsgBuffer [MAXQMSGBUFFERSIZE];
static ULONG ulQmsgBottom = 0;
static ULONG ulQmsgTop = 0;
static HMODULE hModule;
static BOOL bFirstTimePlaybackHook = TRUE;
static HMODULE hModule;
ULONG APIENTRY _export JPHook( HAB hab, BOOL fSkip, PQMSG lpqmsg );
BOOL APIENTRY _export StickyInputHook( HAB hab, PQMSG lpqmsg, USHORT fs )
{
/*
* The lpqmsg parameter points to a queue-message structure.
* Returns FALSE to let the message through to rest of hook
* chain. Returns TRUE to prevent further message processing.
*/
if ((lpqmsg->msg == WM_CHAR) &&
(SHORT2FROMMP(lpqmsg->mp2) == VK_SHIFT) &&
(SHORT1FROMMP(lpqmsg->mp1) & KC_VIRTUALKEY) &&
!(SHORT1FROMMP(lpqmsg->mp1) & KC_KEYUP))
{
if (fAddingTwo)
{
/* Deinstall the input hook. */
if (!hModule)
DosGetModHandle( "STIKHOOK", &hModule );
WinReleaseHook( hab, NULL, HK_INPUT,
StickyInputHook, hModule );
/* JP hook is only going to do 4 messages. */
qmsgBuffer[ulQmsgTop].hwnd = 0L;
qmsgBuffer[ulQmsgTop].msg = WM_CHAR;
qmsgBuffer[ulQmsgTop].mp1 =
MPFROM2SHORT(SHORT1FROMMP(lpqmsg->mp1) & ~KC_KEYUP,
SHORT2FROMMP(lpqmsg->mp1));
qmsgBuffer[ulQmsgTop].mp2 = lpqmsg->mp2;
qmsgBuffer[ulQmsgTop].time = 300;
qmsgBuffer[ulQmsgTop].ptl = lpqmsg->ptl;
ulQmsgTop++;
qmsgBuffer[ulQmsgTop].hwnd = 0L;
qmsgBuffer[ulQmsgTop].msg = WM_CHAR;
qmsgBuffer[ulQmsgTop].mp1 = lpqmsg->mp1;
qmsgBuffer[ulQmsgTop].mp2 = lpqmsg->mp2;
qmsgBuffer[ulQmsgTop].time = 300;
qmsgBuffer[ulQmsgTop].ptl = lpqmsg->ptl;
ulQmsgTop++;
qmsgBuffer[ulQmsgTop].hwnd = 0L;
qmsgBuffer[ulQmsgTop].msg = WM_CHAR;
qmsgBuffer[ulQmsgTop].mp1 =
MPFROM2SHORT(SHORT1FROMMP(lpqmsg->mp1) & ~KC_KEYUP,
SHORT2FROMMP(lpqmsg->mp1));
qmsgBuffer[ulQmsgTop].mp2 = lpqmsg->mp2;
qmsgBuffer[ulQmsgTop].time = 300;
qmsgBuffer[ulQmsgTop].ptl = lpqmsg->ptl;
ulQmsgTop++;
qmsgBuffer[ulQmsgTop].hwnd = 0L;
qmsgBuffer[ulQmsgTop].msg = WM_CHAR;
qmsgBuffer[ulQmsgTop].mp1 = lpqmsg->mp1;
qmsgBuffer[ulQmsgTop].mp2 = lpqmsg->mp2;
qmsgBuffer[ulQmsgTop].time = 300;
qmsgBuffer[ulQmsgTop].ptl = lpqmsg->ptl;
ulQmsgTop++;
/* Install the journal playback hook. */
if (WinSetHook( hab, NULL, HK_JOURNALPLAYBACK, (PFN)&JPHook, hModule ))
WinAlarm( HWND_DESKTOP, WA_NOTE ); //!!!
}
fAddingTwo = !fAddingTwo;
return FALSE;
}
return FALSE;
} /* StickyInputHook */
ULONG APIENTRY _export JPHook( HAB hab, BOOL fSkip, PQMSG lpqmsg )
{
static QMSG qmsgMouse;
static QMSG qmsgCurrent;
static LONG lLastMsgTime = 0L;
static LONG lCurrentMsgTime = 0L;
static LONG lMsgDelay = 0L;
static LONG lDelayRemaining = 0L;
static LONG lLastSequencedEventTime = 0L;
/*------------------------------------------------------*/
/* Store the passed time as the current message time */
/*------------------------------------------------------*/
/*----------------------------------------------*/
/* Note: if fSkip is TRUE, the lpqmsg pointer */
/* will be NULL. */
/*----------------------------------------------*/
if (lpqmsg) {
lCurrentMsgTime = lpqmsg->time;
}
/*------------------------------------------------------*/
/* The system requests that a NEW message be prepared */
/*------------------------------------------------------*/
if (fSkip) {
/*----------------------------------------------*/
/* No more messages on queue - release the hook */
/*----------------------------------------------*/
if (ulQmsgBottom == ulQmsgTop) {
WinReleaseHook (
hab,
0L,
HK_JOURNALPLAYBACK,
(PFN) JPHook,
hModule
);
/*--------------------------------------*/
/* Set a mouse move "in place" message */
/*--------------------------------------*/
qmsgCurrent = qmsgMouse;
#if 0
/*--------------------------------------*/
/* Reinstall the input hook */
/*--------------------------------------*/
WinSetHook (
hab,
0L,
HK_INPUT,
StickyInputHook,
hModule
);
#endif
}
/*----------------------------------------------*/
/* Prepare and pass the next message */
/*----------------------------------------------*/
else {
/*--------------------------------------*/
/* Update the time of last message */
/*--------------------------------------*/
lLastMsgTime = lLastSequencedEventTime;
/*--------------------------------------*/
/* Copy current message from the queue */
/*--------------------------------------*/
qmsgCurrent = qmsgBuffer[ulQmsgBottom];
/*--------------------------------------*/
/* Update the current mouse position so */
/* that the mouse stays put when we */
/* playback */
/*--------------------------------------*/
if (qmsgCurrent.msg == WM_MOUSEMOVE) {
qmsgMouse.mp1 = qmsgCurrent.mp1;
qmsgMouse.mp2 = qmsgCurrent.mp2;
qmsgMouse.ptl.x = qmsgCurrent.ptl.x;
qmsgMouse.ptl.y = qmsgCurrent.ptl.y;
}
/*--------------------------------------*/
/* Update (and wrap) the queue pointer */
/*--------------------------------------*/
ulQmsgBottom++;
if (ulQmsgBottom >= MAXQMSGBUFFERSIZE) {
ulQmsgBottom=0L;
}
/*--------------------------------------*/
/* New message - so set up the delay */
/* timing variables */
/*--------------------------------------*/
lMsgDelay = qmsgCurrent.time;
lDelayRemaining = lMsgDelay - (lCurrentMsgTime - lLastMsgTime);
if (lDelayRemaining < 0) {
lDelayRemaining = 0L;
}
lLastSequencedEventTime = lCurrentMsgTime + lDelayRemaining;
qmsgCurrent.time = lLastSequencedEventTime;
}
}
/*------------------------------------------------------*/
/* The system requests a PEEK at the CURRENT message */
/*------------------------------------------------------*/
else {
/*----------------------------------------------*/
/* Initialize the variables on the first pass */
/*----------------------------------------------*/
if (bFirstTimePlaybackHook) {
bFirstTimePlaybackHook = 0;
lLastMsgTime = 0L;
lCurrentMsgTime = 0L;
lMsgDelay = 0L;
lDelayRemaining = 0L;
lLastSequencedEventTime = 0L;
/*--------------------------------------*/
/* Initialize the default mouse move */
/*--------------------------------------*/
qmsgMouse.hwnd = HWND_DESKTOP;
qmsgMouse.msg = WM_MOUSEMOVE;
qmsgMouse.mp1 = (MPARAM) 0;
qmsgMouse.mp2 = (MPARAM) 0;
qmsgMouse.time = 0L;
qmsgMouse.ptl.x = 0L;
qmsgMouse.ptl.y = 0L;
/*--------------------------------------*/
/* Send the same message as before */
/*--------------------------------------*/
if (ulQmsgBottom == ulQmsgTop) {
qmsgCurrent = qmsgMouse;
}
/*--------------------------------------*/
/* Use the next message in the queue */
/*--------------------------------------*/
else {
qmsgCurrent = qmsgBuffer[ulQmsgBottom];
/*------------------------------*/
/* New message - so set up the */
/* delay timing variables */
/*------------------------------*/
lMsgDelay = qmsgCurrent.time;
lDelayRemaining = lMsgDelay - (lCurrentMsgTime - lLastMsgTime);
if (lDelayRemaining < 0) {
lDelayRemaining = 0L;
}
lLastSequencedEventTime = lCurrentMsgTime + lDelayRemaining;
qmsgCurrent.time = lLastSequencedEventTime;
}
}
/*----------------------------------------------*/
/* Copy current message to the passed pointer */
/*----------------------------------------------*/
if (lpqmsg) {
*lpqmsg = qmsgCurrent;
}
}
/*------------------------------------------------------*/
/* Update & return the remaining delay for this message */
/*------------------------------------------------------*/
lDelayRemaining = lMsgDelay - (lCurrentMsgTime - lLastMsgTime);
if (lDelayRemaining < 0 ) {
lDelayRemaining = 0L;
}
return ((ULONG)lDelayRemaining);
}