//========================================================================
// 
//  WINPLIB.C - A library module for WINPTR.C
//
//  (c) Douglas Boling 1992
//
//  For better readability, set tab stops to every 3 characters.
//
//========================================================================

#include <windows.h>
#include "winptr.h"

VOID		FAR PASCAL 	KeyHookProc (int, WORD, LONG);
HCURSOR	MarkCursor	(void);

FARPROC	lpfnNextHook;
HANDLE	hInst;
HCURSOR	hCursor, hSizeCursor;
HCURSOR	hArrowCursor, hNSCursor, hWECursor, hNWSECursor, hNESWCursor;
HCURSOR	hPrevCursor;

POINT		pLastPoint = {0,0};
DWORD		dwLastTime;
WORD		wCurID = 1;
WORD		wMoveTrig = 10, wTimeTrig = 100;
BYTE		ucHooked = 0;
BYTE		ucArrowOnly = 0;

//=======================================================================
//
// Library initialization and terminataion functions
//
//=======================================================================
//------------------------------------------------------------------------
// LibMain - DLL initialization routine
//------------------------------------------------------------------------
int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, WORD wHeapSize,
	                     LPSTR lpszCmdLine) {

	hInst = hInstance;
	hCursor = LoadCursor (hInstance, MAKEINTRESOURCE (1));

	if (hCursor == 0)
		return 0;

	hSizeCursor = LoadCursor (hInstance, MAKEINTRESOURCE (10));

	hArrowCursor = LoadCursor (0, IDC_ARROW);
	hNSCursor = LoadCursor (0, IDC_SIZENS);
	hWECursor = LoadCursor (0, IDC_SIZEWE);
	hNESWCursor = LoadCursor (0, IDC_SIZENESW);
	hNWSECursor = LoadCursor (0, IDC_SIZENWSE);

	return 1;
}
//------------------------------------------------------------------------
// WEP - DLL termination routine
//------------------------------------------------------------------------
int FAR PASCAL WEP (int nParameter) {
	if (ucHooked != 0)
	 	SetWindowsHook (WH_GETMESSAGE, lpfnNextHook);

	return 1;
}
//------------------------------------------------------------------------
// Mark cursor - Changes the cursor to the highlighted cursor
//------------------------------------------------------------------------
HCURSOR MarkCursor (void) {
	HCURSOR	hOldCursor;

	hOldCursor = SetCursor (hCursor);

	if (ucArrowOnly && hOldCursor != hArrowCursor) {
		SetCursor (hOldCursor);
		return hOldCursor;
	}
	if (hOldCursor != hArrowCursor) {
		if (hOldCursor == hCursor) return 0; 

		if (hOldCursor == hNSCursor || hOldCursor == hWECursor ||
		    hOldCursor == hNWSECursor || hOldCursor == hNESWCursor ||
		    hOldCursor == hSizeCursor)
			SetCursor (hSizeCursor);
	}	
	return hOldCursor;
}

//========================================================================
//
// Hook function
//
//========================================================================
VOID FAR PASCAL MsgHookProc (int code, WORD wParam, LONG lParam) {

	int		sDiffX, sDiffY;
	DWORD		rc;
	LPMSG		lpmMsg;
	HCURSOR	hTemp;

	rc = DefHookProc (code, wParam, lParam, &lpfnNextHook);
	if (code < 0) return;

	lpmMsg = lParam;

	if ((lpmMsg->message == WM_MOUSEMOVE) ||
	    (lpmMsg->message == WM_NCMOUSEMOVE)) {

		sDiffX = lpmMsg->pt.x - pLastPoint.x;
		sDiffY = lpmMsg->pt.y - pLastPoint.y;
		if (sDiffX < 0) sDiffX = pLastPoint.x - lpmMsg->pt.x;
		if (sDiffY < 0) sDiffY = pLastPoint.y - lpmMsg->pt.y;

		if ((sDiffX > (int) wMoveTrig) || (sDiffY > (int) wMoveTrig)) 
			dwLastTime = lpmMsg->time;

		pLastPoint.x = lpmMsg->pt.x;
		pLastPoint.y = lpmMsg->pt.y;
	}
	if ((lpmMsg->time - dwLastTime) < (DWORD) wTimeTrig) {
		if (hTemp = MarkCursor ())
			hPrevCursor = hTemp;
	}
	return;
}

//========================================================================
//
// Library exported functions
//
//========================================================================
//------------------------------------------------------------------------
//
// GetStatus - Returns Status information
//
//------------------------------------------------------------------------
VOID FAR PASCAL GetStatus (PHOOKSTAT phsStatus){

	phsStatus -> wMoveTrig = wMoveTrig;
	phsStatus -> wTimeTrig = wTimeTrig;
	phsStatus -> wCursorID = wCurID;
	if (ucHooked)
		phsStatus -> bEnabled = TRUE;
	else
		phsStatus -> bEnabled = FALSE;
	if (ucArrowOnly)
		phsStatus -> bArrowOnly = TRUE;
	else
		phsStatus -> bArrowOnly = FALSE;
 	return;
}
//------------------------------------------------------------------------
//
// LocatePointer - Locates the Windows Cursor by changing the cursor shape
// 
//------------------------------------------------------------------------
BOOL FAR PASCAL LocatePointer (VOID) {

	return MarkCursor ();
}
//------------------------------------------------------------------------
//
// SetLocate - Enables and disables the pointer locate function
// 
//------------------------------------------------------------------------
BOOL FAR PASCAL SetLocate (BOOL bEnable) {

	if (bEnable) {
		if (ucHooked == 0) {
			lpfnNextHook = SetWindowsHook (WH_GETMESSAGE, 
		                               GetProcAddress (hInst, "MsgHookProc"));
			ucHooked++;
		}
	} else {
		if (ucHooked != 0) {
	 		SetWindowsHook (WH_GETMESSAGE, lpfnNextHook);
			ucHooked--;
		}
	}
	return TRUE;
}
//------------------------------------------------------------------------
//
// SetTriggers - Sets the Trigger values.
//
//------------------------------------------------------------------------
BOOL FAR PASCAL SetTriggers (int sNewMTrig, int sNewTTrig) {

	wMoveTrig = sNewMTrig;
	wTimeTrig = sNewTTrig;
	
 	return TRUE;
}
//------------------------------------------------------------------------
//
// SetCursorID - Sets the Cursor to be used
//
//------------------------------------------------------------------------
BOOL FAR PASCAL SetCursorID (WORD wCursorID) {
	HCURSOR	hCurTemp;

	if (hCurTemp = LoadCursor (hInst, MAKEINTRESOURCE (wCursorID))) {
		hCursor = hCurTemp;
		wCurID = wCursorID;

		if (wCursorID % 2)
			hSizeCursor = LoadCursor (hInst, MAKEINTRESOURCE (20));
		else
			hSizeCursor = LoadCursor (hInst, MAKEINTRESOURCE (21));

		dwLastTime = 0;
		pLastPoint.x = 0;
		pLastPoint.y = 0;
		return TRUE;
	}	
 	return FALSE;
}
//------------------------------------------------------------------------
//
// SetArrowOnly - Sets the Change Arrow Cursor Only Flag
//
//------------------------------------------------------------------------
VOID FAR PASCAL SetArrowOnly (BOOL bArrowOnly) {

	ucArrowOnly = (BYTE) bArrowOnly;	
 	return;
}

