#include <exec/types.h>
#include <exec/io.h>
#include <intuition/intuition.h>
#include <devices/conunit.h>

#define EOF -1
#define GRAPHICS_REV 29
#define INTUITION_REV 29

void myexit(), mysetup(), myprintf(), queueread();
int mygetc();

extern struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

static struct IOStdReq *conreader, conrequest;
static struct MsgPort *conreadport;
struct Window *mywindow;
extern char WindowTitle[];
static char conchar;

static struct NewWindow NewWindow = {
   0,1,640,199,-1,-1,	/* left, top, width, height, detail, block */
   CLOSEWINDOW,
   WINDOWDEPTH | WINDOWDRAG | ACTIVATE,
   NULL, NULL, WindowTitle,
   NULL, NULL, 640, 199, 640, 199, WBENCHSCREEN };

/* initialize the window so we can read and write to it */
void mysetup()
{
   if ((IntuitionBase = (struct IntuitionBase *)
      OpenLibrary("intuition.library", INTUITION_REV)) == NULL)
      exit(1);

   if ((GfxBase = (struct GfxBase *)
      OpenLibrary("graphics.library", GRAPHICS_REV)) == NULL)
      exit(2);

   if ((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
      exit(3);

/* create a port to receive messages about completed operations */
   if ((conreadport = CreatePort("my.con.read", 0)) == NULL)
      exit(4);

/* construct a request for that port */
   if ((conreader = CreateStdIO(conreadport)) == NULL)
      exit(5);

   conreader->io_Data = (APTR)mywindow;
   conreader->io_Length = sizeof(*mywindow);

   if (OpenDevice("console.device", 0, conreader, 0) != 0)
      myexit(6);

/* copy so we have a read request structure */
   conrequest.io_Device = conreader->io_Device;
   conrequest.io_Unit = conreader->io_Unit;

   queueread();
}

void myputc(c)	/* write a single character to our window */
char c;
{
   if (mywindow == NULL) mysetup();

   conrequest.io_Command = CMD_WRITE;
   conrequest.io_Data = (APTR)&c;
   conrequest.io_Length = 1;
   DoIO(&conrequest);
}

void queueread()
{
   conreader->io_Command = CMD_READ;
   conreader->io_Data = &conchar;
   conreader->io_Length = 1;
   SendIO(conreader);
}

int mygetc()
{
   struct IntuiMessage *GetMsg();
   char c = 0;

   if (mywindow == NULL) mysetup();

/* if there hasn't been a response to the last read request, wait for it */
   while((GetMsg(conreadport) == NULL)) WaitPort(conreadport);
/* get what the response character was */
   c = conchar;
/* and queue up for another one */
   queueread();
   return((c == 0x1c) ? EOF : c);
}

void myputs(str)	/* write a string to our window */
char *str;
{
   if (mywindow == NULL) mysetup();

   conrequest.io_Command = CMD_WRITE;
   conrequest.io_Data = (APTR)str;
   conrequest.io_Length = strlen(str);
   DoIO(&conrequest);
   myputc('\n');	/* don't forget the newline for the string */
}

/* write a formatted string to our window */
void myprintf(str,v1,v2,v3,v4,v5,v6,v7,v8,v9)
char *str;
long v1,v2,v3,v4,v5,v6,v7,v8,v9;
{
   char buff[256];

   if (mywindow == NULL) mysetup();

   conrequest.io_Command = CMD_WRITE;
   conrequest.io_Data = (APTR)buff;
   conrequest.io_Length = sprintf(buff,str,v1,v2,v3,v4,v5,v6,v7,v8,v9);
   DoIO(&conrequest);
}

/* close up everything and leave the program */
void myexit(code)
int code;
{
   if (mywindow != NULL)
      {
      CloseDevice(conreader);
      DeleteStdIO(conreader);
      DeletePort(conreadport);
      CloseWindow(mywindow);
      CloseLibrary(GfxBase);
      CloseLibrary(IntuitionBase);
      }
   _exit(code);
}
