/**************************************************************************/
/**         SpyMouse.c (SYSGADS) Jan 1991  L.v.Jeurissen  (LvJ)          **/
/**************************************************************************/

/**************************************************************************/
/**    This is an example for the use of systemgadgets, however it may   **/
/**    be, that it's for some people a helpfull tool. For who want to    **/
/**    use systemgadgets take a look at Data.c (gadget structs) and the  **/
/**    while(TRUE) loop in SpyMouse.c, Important: remove SYSGADS before  **/
/**    closing your Window.  Go and make our Windows a little better to  **/
/**    look at.                                       LvJ  1991          **/
/**                                                                      **/
/**    Mouse Spy  V1.0 is  a user friendly program that reads MouseX and **/
/** MouseY in the Workbench screen, and  all windows  opened in  it, and **/
/** displays them in an own window;                                      **/
/** Mouse Spy  V1.0 can  be loaded from Workbench or CLI, just enter the **/
/** name in CLI or double click  the icon  in Workbench.  Mouse Spy V1.0 **/
/** will detach  itself from CLI, so that you can exit the CLI. When the **/
/** left mouse button is pressed the current mouse  position is  used as **/
/** an offset,  which is  subtracted from  MouseX and MouseY. The offset **/
/** will remain valid as long as  you hold  down the  left mouse button. **/
/** For example you want to know the difference between two pixels A and **/
/** B. Place the mouse pointer on pixel A  or B  (look carefully), press **/
/** and hold  the left  mouse button,  and move  the mouse  to the other **/
/** pixel A  or B.  In the  Mouse Spy  V1.0 window  the coordinates will **/
/** change positive  or negative  (according to the direction). You have **/
/** to read the value before the mouse button is released, otherwise you **/
/** must repeat the whole procedure. In the future I will (try to) add a **/
/** magnifyer so that one can  spare  the  eyes.  Anyone  may  sell this **/
/** proggy (only  for big  money, and only to idiots who want to get rid **/
/** of their money), sell (only to idiots), throw away, change, etc.     **/
/** However, don't kill for it.                                          **/ 
/**                                                                      **/
/** Small? problems: When the  right mouse  button is  pressed Mouse Spy **/
/**                  V1.0, and  many others  with me, will be thrown out **/
/**                  of work. So no mouse update,  and the  same happens **/
/**                  when with  the LMB when you move an icon or window. **/
/**                  Mother Intuition doesn't allow her children to play **/
/**                  when she is at work.                                **/
/**                                                                      **/
/**                  I hope  to solve  bad visibility by using the mouse **/
/**                  pointer as a  magnification  device.  I  don't know **/
/**                  when as  I don't need Mouse Spy V1.0 at the moment, **/
/**                  so it remains unused.                               **/
/**                                                                      **/
/** The source  speaks  for  itself.  In  case  you  don't  want  to use **/
/** Preincludes, the  includes can  be found in 'Include.c'. To minimize **/
/** program size _cli_parse()  and  _wb_parse()  are  replaced by  stubs **/
/** so you don't have to worry about overrule messages when linking.     **/
/**                                                                      **/
/** Jan 19 04:09:41 1991        for information and       L.V. Jeurissen **/
/**                             bug reports contact       Paterstraat 35 **/
/**                                                       6828 AG        **/
/**                                                       Arnhem         **/
/** Support GreanPeace and Me                             085-455693     **/
/**                                                                      **/
/** Used: AREXX CED INDENT MANX 3.6A A500 A501 A590+ A1010               **/
/**************************************************************************/

#include "data.c"

void _wb_parse()
{
}
void _cli_parse()
{
}

void Spy();
int GetAbsoluteValueFrom();
void FillITextBuffer();
int CheckLeftMouseButton();
void SetMousePointer();
void ClearMousePointer();
void LoopThisCode();
void DoThisCodeFirst();
long DoThisCodeLast();

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Window *Window;
struct Preferences *OldPrefs, *NewPrefs, *PrefsBuffers;

int MX, MY, MXold, MYold, Flag = 0;
USHORT *ChipImageBlock = NULL;

#ifndef A1000			/* Need this for MANX detach.o */
long _BackGroundIO = NULL;
long _stack = NULL;
char *_procname = "Mouse Spy V1.0";
long _priority = -1L;
#endif

void main()
{
    DoThisCodeFirst();
    LoopThisCode();
}

void LoopThisCode()
{
    register struct IntuiMessage *message;

    while (TRUE) {
	Spy();

	while (message = (struct IntuiMessage *) GetMsg(Window->UserPort)) {
	    ReplyMsg((struct Message *) message);
	    if (message->Class == CLOSEWINDOW) {
		DoThisCodeLast(RETURN_OK);
	    }
	    if (message->Class == GADGETUP && message->IAddress == (APTR) & PointerGadget) {
		((Flag) ? (ClearMousePointer()) : (SetMousePointer()));
	    }
	}
    }
}

void Spy()
{
    if (CheckLeftMouseButton() == 0) {
	MXold = Window->WScreen->MouseX;
	MYold = Window->WScreen->MouseY;
	while (CheckLeftMouseButton() == 0) {
	    MX = Window->WScreen->MouseX;
	    MY = Window->WScreen->MouseY;
	    FillITextBuffer(GetAbsoluteValueFrom(MX - MXold), GetAbsoluteValueFrom(MY - MYold));
	    if (MXold > MX)
		buffer[3] = '-';
	    if (MYold > MY)
		buffer[10] = '-';
	    PrintIText(Window->RPort, &IText, 26L, 1L);
	}
    }
    MX = Window->WScreen->MouseX;
    MY = Window->WScreen->MouseY;
    FillITextBuffer(MX, MY);
    PrintIText(Window->RPort, &IText, 26L, 1L);
}

int GetAbsoluteValueFrom(getal)
register int getal;
{
    if (getal < 0)
	return (-getal);
    return (getal);
}

void FillITextBuffer(x, y)
register int x, y;
{
    register int count;
    static char temp[15] = " X: 000 Y: 000 ";

    for (count = 0; count < 15; count++)
	buffer[count] = temp[count];
    count = 6;
    do {
	buffer[count] = ((int) (x % 10) + '0');
	count--;
    } while ((x /= 10) != 0);
    count = 13;
    do {
	buffer[count] = ((int) (y % 10) + '0');
	count--;
    } while ((y /= 10) != 0);
}

int CheckLeftMouseButton()
{
    return (*(char *) 0xbfe001 >> 6 & 1);
}

void SetMousePointer()
{
    SetPrefs(NewPrefs, 232L, FALSE);
    Flag = 1;
}

void ClearMousePointer()
{
    SetPrefs(OldPrefs, 232L, FALSE);
    Flag = 0;
}

void DoThisCodeFirst()
{
    register int count;
    if ((ChipImageBlock = (USHORT *) AllocMem(960L, MEMF_CHIP)) == NULL)
	DoThisCodeLast(RETURN_WARN);
    movmem(ImageBlock, ChipImageBlock, 960);
    PointerImage.ImageData = (USHORT *) (ChipImageBlock + 0L);
    PointerSelectImage.ImageData = (USHORT *) (ChipImageBlock + 40L);
    OnTopImage.ImageData = (USHORT *) (ChipImageBlock + 80L);
    OnTopSelectImage.ImageData = (USHORT *) (ChipImageBlock + 120L);
    DownUnderImage.ImageData = (USHORT *) (ChipImageBlock + 160L);
    DownUnderSelectImage.ImageData = (USHORT *) (ChipImageBlock + 200L);
    DragWindowImage.ImageData = (USHORT *) (ChipImageBlock + 240L);
    CloseWindowImage.ImageData = (USHORT *) (ChipImageBlock + 400L);
    CloseWindowSelectImage.ImageData = (USHORT *) (ChipImageBlock + 440L);
    if ((IntuitionBase = (struct IntuitionBase *)
	 OpenLibrary("intuition.library", 0L)) == NULL)
	DoThisCodeLast(RETURN_WARN);
    if ((GfxBase = (struct GfxBase *)
	 OpenLibrary("graphics.library", 0L)) == NULL)
	DoThisCodeLast(RETURN_WARN);
    if ((PrefsBuffers = (struct Preferences *) AllocMem(464L, MEMF_CLEAR | MEMF_PUBLIC)) == NULL)
	DoThisCodeLast(RETURN_WARN);
    OldPrefs = GetPrefs((struct Preferences *) PrefsBuffers, 232L);
    NewPrefs = GetPrefs((struct Preferences *) PrefsBuffers + 1L, 232L);
    for (count = 0; count < 35; count++)
	NewPrefs->PointerMatrix[count] = ImageBlock[480L + count];
    NewPrefs->XOffset = -9;
    NewPrefs->YOffset = -7;
    if ((Window = (struct Window *) OpenWindow(&NewWindow)) == NULL)
	DoThisCodeLast(RETURN_WARN);
}

long DoThisCodeLast(returncode)
long returncode;
{
    ClearMousePointer();
    RemoveGList(Window, &CloseWindowGadget, -1L); /** important !!!! **/
    if (Window)
	CloseWindow(Window);
    if (GfxBase)
	CloseLibrary(GfxBase);
    if (IntuitionBase)
	CloseLibrary(IntuitionBase);
    if (PrefsBuffers)
	FreeMem(PrefsBuffers, 464L);
    if (ChipImageBlock)
	FreeMem(ChipImageBlock, 960L);
    exit(returncode);
}
