/*
 * mouse.c v1.0 by Chris Ludwig
 */

#include	<exec/types.h>

#include	<libraries/dos.h>
#include	<libraries/dosextens.h>

#include	<devices/input.h>
#include	<devices/inputevent.h>

#include	<clib/rexxsyslib_protos.h>
#include	<clib/alib_protos.h>
#include	<clib/exec_protos.h>
#include	<clib/dos_protos.h>

#include	<rexx/storage.h>
#include	<rexx/rxslib.h>

#include <stdlib.h>
#include	<stdio.h>
#include	<string.h>

#include	"SimpleRexx.h"

char *stptok(char *,char *,int,char *);
int stcd_i(char *,int *);


/* input.device stuff */
struct MsgPort *inputdevport;
struct InputEvent phony;
struct IOStdReq *inputrequest;
BYTE inputopenerror;

AREXXCONTEXT	RexxStuff;

void Quit(char whytext[],UBYTE level)
{
	if (!inputopenerror) CloseDevice((struct IORequest *) inputrequest);

	if (inputrequest) DeleteStdIO(inputrequest);

	if (inputdevport) DeletePort(inputdevport);

	FreeARexx(RexxStuff);

	printf("%s\n",whytext);
	Exit(level);
}


/*
 * Lattice control-c stop...
 */
int CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
int chkabort(void) { return(0); }  /* really */


void click(UWORD code)
{
printf("in click()\n");

	phony.ie_NextEvent = NULL;
	phony.ie_Class = IECLASS_RAWMOUSE;
	phony.ie_TimeStamp.tv_secs = 0;
	phony.ie_TimeStamp.tv_micro = 0;
	phony.ie_Code = code;					/* button down */
	phony.ie_Qualifier = 0;
	phony.ie_X = 0;
	phony.ie_Y = 0;

	inputrequest -> io_Command = IND_WRITEEVENT;
	inputrequest -> io_Flags = 0;
	inputrequest -> io_Length = sizeof(struct InputEvent);
	inputrequest -> io_Data = (APTR)&phony;

	DoIO((struct IORequest *)inputrequest);


	phony.ie_NextEvent = NULL;
	phony.ie_Class = IECLASS_RAWMOUSE;
	phony.ie_TimeStamp.tv_secs = 0;
	phony.ie_TimeStamp.tv_micro = 0;
	phony.ie_Code = code | IECODE_UP_PREFIX;	/* button up */
	phony.ie_Qualifier = 0;
	phony.ie_X = 0;
	phony.ie_Y = 0;

	inputrequest -> io_Command = IND_WRITEEVENT;
	inputrequest -> io_Flags = 0;
	inputrequest -> io_Length = sizeof(struct InputEvent);
	inputrequest -> io_Data = (APTR)&phony;

	DoIO((struct IORequest *)inputrequest);
}


void move(LONG mousex, LONG mousey)
{
	/* send phony mouse message to input stream */

	phony.ie_NextEvent = NULL;
	phony.ie_Class = IECLASS_POINTERPOS;
	phony.ie_TimeStamp.tv_secs = 0;
	phony.ie_TimeStamp.tv_micro = 0;
	phony.ie_Code = 0;
	phony.ie_Qualifier = 0;
	phony.ie_X = mousex;
	phony.ie_Y = mousey;

	inputrequest -> io_Command = IND_WRITEEVENT;
	inputrequest -> io_Flags = 0;
	inputrequest -> io_Length = sizeof(struct InputEvent);
	inputrequest -> io_Data = (APTR)&phony;

	DoIO((struct IORequest *)inputrequest);
}


/*
 * A *VERY* simple and simple-minded example of using the SimpleRexx.c code.
 *
 *
 * Note: You will want to RUN this program or have another shell available such
 *       that you can still have access to ARexx...
 */
void main(int argc,char *argv[])
{
short	loopflag=TRUE;
ULONG	signals;

int x, y, length;

	if ((inputdevport=CreatePort(0,0)) == NULL)
		Quit("Couldn't create a port for input.device",25);


	if ((inputrequest=CreateStdIO(inputdevport)) == NULL)
		Quit("Couldn't create request block for input device",25);


	if ((inputopenerror=OpenDevice("input.device",0,(struct IORequest *)inputrequest,0)) != 0)
		Quit("Couldn't open input.device",25);

	/*
	 * Note that SimpleRexx is set up such that you do not
	 * need to check for an error to initialize your REXX port
	 * This is so your application could run without REXX...
	 */
	RexxStuff=InitARexx("mouse","mouse");

	if (argc)
	{
		if (RexxStuff) printf("Send commands to port %s\n",ARexxName(RexxStuff));
		else printf("ARexx is not available\n");
	}

	while (loopflag)
	{
		signals=ARexxSignal(RexxStuff);

		if (signals)
		{
			struct	RexxMsg		*rmsg;

			signals=Wait(signals);

			/*
			 * Process the ARexx messages...
			 */
			while (rmsg=GetARexxMsg(RexxStuff))
			{
			char	cBuf[24];
			char	*nextchar;
			char	*error=NULL;
			char	*result=NULL;
			long	errlevel=0;

				nextchar=stptok(ARG0(rmsg),cBuf,24," ,");
				if (*nextchar) nextchar++;

				if (!stricmp("CLICK",cBuf))
				{
					nextchar=stptok(nextchar,cBuf,24," ,");
					if (*nextchar) nextchar++;

					if (!stricmp("LEFT",cBuf))
					{
						click(IECODE_LBUTTON);
					}
					else if (!stricmp("MIDDLE",cBuf))
					{
						click(IECODE_MBUTTON);
					}
					else if (!stricmp("RIGHT",cBuf))
					{
						click(IECODE_RBUTTON);
					}
					else
					{
						/* Default to left button */
						click(IECODE_LBUTTON);
					}
				}
				else if (!stricmp("MOVE",cBuf))
				{
					nextchar=stptok(nextchar,cBuf,24," ,");
					if (*nextchar) nextchar++;

					length=stcd_i(cBuf,&x);

					nextchar=stptok(nextchar,cBuf,24," ,");
					if (*nextchar) nextchar++;

					length=stcd_i(cBuf,&y);


					move((LONG) x,(LONG) y);
				}
				else if (!stricmp("VERSION",cBuf))
				{
					result="mouse v1.0";
				}
				else if (!stricmp("QUIT",cBuf))
				{
					loopflag=FALSE;
				}
				else
				{
					error="Unknown command";
					errlevel=20;
				}

				if (error)
				{
					SetARexxLastError(RexxStuff,rmsg,error);
				}
				ReplyARexxMsg(RexxStuff,rmsg,result,errlevel);
			}

		}
		else loopflag=FALSE;
	}
	Quit("QUIT command received.\n",0);
}
