/* TWin.c - Text Server for debugging, by Talin. */
/* to start:

		Run TWin.

	to print text:

		send a message to the message port "Text", where the ln_Name of the
		message points to a null-terminated text string to be printed.

	to quit TWin - click on close box.

	example calling code:

TaskWrite(msg) char *msg;
{	struct MsgPort *tport, *rport, *FindPort();
	struct Message mymessage;
	if (rport = CreatePort(NULL,0))
	{	rport->mp_Flags = PA_SIGNAL;
		Forbid();
		if (tport = FindPort("Text"))
		{	mymessage.mn_Node.ln_Name = msg;
			mymessage.mn_Node.ln_Pri = 0;
			mymessage.mn_Node.ln_Type = NT_MESSAGE;
			mymessage.mn_ReplyPort = rport;
			PutMsg(tport,&mymessage);
			WaitPort(rport);
		}
		Permit();
		DeletePort(rport);
	}
}

*/


#include "exec/types.h"
#include "graphics/gfx.h"
#include "graphics/gfxbase.h"
#include "libraries/diskfont.h"
#include "intuition/intuition.h"

struct Library 			*IntuitionBase=NULL,
						*GfxBase=NULL,
						*OpenLibrary();
struct Window 			*Window=NULL,
						*OpenWindow();
struct RastPort 		*rp;

struct IOStdReq 		write_req;				/* console io request */
struct MsgPort			*con_port=NULL,			/* console message port */
						*task_port=NULL,		/* message port from other tasks */
						*CreatePort();

struct NewWindow text_window =
{	50,50,400,100, 2,1,
 	CLOSEWINDOW,
	NOCAREREFRESH | SIMPLE_REFRESH | WINDOWSIZING | WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG,
	NULL,NULL,(UBYTE *)"Task Output Server",NULL,NULL,100,50,1000,1000,WBENCHSCREEN,
};

#define SCAT goto exit_pgm						/* standard escape function */

_main()
{	short i;

	if ((IntuitionBase = OpenLibrary("intuition.library",0)) == NULL) SCAT;
	if ((GfxBase = OpenLibrary("graphics.library",0)) == NULL) SCAT;

	if ((Window = OpenWindow(&text_window)) == NULL) SCAT;
	rp = Window->RPort;
	SetAPen(rp,3); SetBPen(rp,2);

	if (!(con_port = CreatePort("ConRead",0))) SCAT;
	if (!(task_port = CreatePort("Text",0))) SCAT;
	task_port->mp_Flags = PA_SIGNAL;

	write_req.io_Data = (APTR)Window;							/* open console */
	write_req.io_Length = sizeof(* Window);
	write_req.io_Message.mn_Node.ln_Type = NT_MESSAGE;
	write_req.io_Message.mn_Node.ln_Pri = 0;
	write_req.io_Message.mn_ReplyPort = con_port;
	if ( OpenDevice("console.device",0,&write_req,0) != 0) SCAT;

	while (TRUE)
	{	LONG	dsig = 1 << task_port->mp_SigBit,				/* task signal */
				isig = 1 << Window->UserPort->mp_SigBit,		/* intuition sig */
				signals;										/* sigs recv'd */
		void *GetMsg();

		signals = Wait(dsig | isig);							/* wait for sigs */

		if (signals & isig)										/* if intuition */
		{	struct IntuiMessage 	*message;					/* intuition msg */
			long					class;

			while (message = GetMsg(Window->UserPort))			/* get messages */
			{	class = message->Class;							/* get msg class */
				ReplyMsg(message);								/* reply */

				if (class == CLOSEWINDOW) SCAT;					/* close the window */
			}
		}
		
		if (signals & dsig)										/* if another task */
		{	struct Message *message;							/* exec message */

			while (message = GetMsg(task_port))					/* get message */
			{	write_req.io_Command = CMD_WRITE;				/* write to console */
				write_req.io_Data = (APTR)(message->mn_Node.ln_Name);  /* string */
				write_req.io_Length = -1;						/* null terminate */
				DoIO(&write_req);								/* do it */

				ReplyMsg(message);								/* reply */
			}
		}
	}

exit_pgm:														/* clean up */
	if (write_req.io_Device) CloseDevice(&write_req);
	if (con_port) DeletePort (con_port);
	if (task_port) DeletePort (task_port);
	if (Window) CloseWindow(Window);
	if (GfxBase) CloseLibrary(GfxBase);
	if (IntuitionBase) CloseLibrary(IntuitionBase);
}
