/*
:ts=4

	ipctest.c

	IPC test program, loads and launches ipcsubproc and interacts with it.
	ipcsubproc is pure and re-entrant, so it can be launched several times
	from the same seglist, if needed.

	Written by Harry "Piru" Sintonen <sintonen@iki.fi>.
	This source code is Public Domain.
*/

#include <exec/libraries.h>
#include <dos/dos.h>
#include <dos/dostags.h>

#include <proto/exec.h>
#include <proto/dos.h>

#include "ipc.h"

#ifdef __MORPHOS__
/* Tell MorphOS this is a native MOS application and not PUP */
const LONG __amigappc__ = 1;
const LONG __abox__ = 1;
#endif

struct ExecBase *SysBase;
struct DosLibrary *DOSBase;

int main(void)
{
	int ret = RETURN_FAIL;

	SysBase = *((struct ExecBase **) 4);

	DOSBase = (APTR) OpenLibrary("dos.library", 37);
	if (DOSBase)
	{
		struct MsgPort *replyport;

		ret = RETURN_ERROR;

		replyport = CreateMsgPort();
		if (replyport)
		{
			BPTR seglist;

			seglist = LoadSeg("PROGDIR:ipcsubproc");
			if (seglist)
			{
				struct Process *proc;
				struct IPCMsg ipcmsg;
				struct MsgPort *ipcport;

				proc = CreateNewProcTags(NP_Seglist,     seglist,
#ifdef __MORPHOS__
				                         NP_CodeType,    CODETYPE_PPC,
#endif
				                         NP_FreeSeglist, FALSE,
				                         NP_Name,        (ULONG) "ipcsubproc",
				                         NP_WindowPtr,   -1,
				                         TAG_DONE);
				if (proc)
				{
					ipcmsg.ipc_msg.mn_ReplyPort = replyport;
					ipcmsg.ipc_msg.mn_Length    = sizeof(struct IPCMsg);
					ipcmsg.ipc_action           = IPCA_STARTUP;
					PutMsg(&proc->pr_MsgPort, &ipcmsg.ipc_msg);
					WaitPort(replyport);
					(void) GetMsg(replyport);

					/* result is port to be used for further IPC messaging, or NULL */
					ipcport = ipcmsg.ipc_port;
				}
				else
					ipcport = NULL;

				/* Did it start ok? */
				if (ipcport)
				{
					Printf("ipcsubproc started...\n");

					Delay(20);
					Printf("instructing ipsubproc to DisplayBeep(NULL)... "); Flush(Output());

					ipcmsg.ipc_msg.mn_ReplyPort = replyport;
					ipcmsg.ipc_msg.mn_Length    = sizeof(struct IPCMsg);
					ipcmsg.ipc_action           = IPCA_BEEP;
					ipcmsg.ipc_screen           = NULL;
					PutMsg(ipcport, &ipcmsg.ipc_msg);
					WaitPort(replyport);
					(void) GetMsg(replyport);

					Printf("done!\n");

					Delay(20);
					Printf("instructing ipsubproc to terminate... "); Flush(Output());

					ipcmsg.ipc_msg.mn_ReplyPort = replyport;
					ipcmsg.ipc_msg.mn_Length    = sizeof(struct IPCMsg);
					ipcmsg.ipc_action           = IPCA_QUIT;
					PutMsg(ipcport, &ipcmsg.ipc_msg);
					ipcport = NULL; /* ipcport is no longer valid! */
					WaitPort(replyport);
					(void) GetMsg(replyport);

					Printf("done!\n");

					Delay(20);

					ret = RETURN_OK;
				}
				else
					Printf("ipcsubproc failed to start!\n");

				UnLoadSeg(seglist);
			}
			else
			{
				PrintFault(IoErr(), NULL);
				Printf("could not LoadSeg \"PROGDIR:ipcsubproc\"\n");
			}

			DeleteMsgPort(replyport);
		}
		else
			Printf("Could not create MsgPort!\n");

		CloseLibrary((APTR) DOSBase);
	}

	return ret;
}