
/*
 *  FTEK.C
 *
 *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
 *
 *  FTEK [-Nnet] [port]
 */

#include <stdio.h>
#include <typedefs.h>
#include "/dnet/channel.h"

#include "/server/servers.h"
#include "tek.h"

/* from tek */
extern struct Window *TekWindow;
extern struct Screen *TekScreen;

TA Ta = { (ubyte *)"topaz", 8 };

ITEXT IText[] = {
    { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"Flush"          },
    { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"Quit"          }
};

ITEM Item[] = {
    { &Item[1], 0, 0, 80, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[0], NULL, 'o' },
    { NULL,	0,10, 80, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[1], NULL, 'q' }
};

MENU Menu[] = {
    { NULL, 0, 0, 80, 20, MENUENABLED, "Control", &Item[0] }
};


NW Nw = {
    0, 0, 640, 200, -1, -1,
    NEWSIZE|CLOSEWINDOW|MENUPICK,
    WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|ACTIVATE,
    NULL, NULL, (UBYTE *)"FTEK  Openning, Wait", NULL, NULL,
    32, 32, -1, -1, WBENCHSCREEN
};

WIN *Win;

int Enable_Abort;
int NotDone = 1;
char Buf[512];
char Term[64] = { "FTEK (UNNAMED SHELL)" };
char Cc;

extern void *OpenWindow();
extern void *GetMsg();
extern void *CreatePort();

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
long chan;

main(ac,av)
char *av[];
{
    long n;
    long imask, conmask, dmask, mask;
    IOCON *iocr, *iocw;
    char portspec = 0;
    char *host = NULL;
    uword port = PORT_IALPHATERM;

    {
	register short i;
	for (i = 1; i < ac; ++i) {
	    if (strncmp(av[i], "-N", 2) == 0) {
		host = av[i] + 2;
		continue;
	    }
	    portspec = 1;
	    port = atoi(av[i]);
	}
    }
    if (portspec)
	printf("Using port %ld\n", port);
    Enable_Abort = 0;
    IntuitionBase = OpenLibrary("intuition.library", 0);
    GfxBase = OpenLibrary("graphics.library", 0);
    Win = OpenWindow(&Nw);
    if (Win == NULL)
	goto e1;
    OpenConsole(Win, &iocr, &iocw);
    if (iocr == NULL || iocw == NULL)
	goto e3;

    /*
     *	We delay here to allow DNET to go through its RESTART sequence
     *	(when DNET automatically runs FTERM, it does so to quickly).
     *	Such a hack!
     */

/*    Delay(50 * 4);   */
    chan = DOpen(host, port, 20, 15);

    if (!chan) {
	puts("Unable to connect");
	goto e3;
    }
    /* start tek part up */

    InitTekItems();
    InitTekMenu();
    InitTekDev(Win);

    DQueue(chan, 32);
    SetMenuStrip(Win, Menu);
    SetWindowTitles(Win, Term, -1);
    imask   = 1 << Win->UserPort->mp_SigBit;
    dmask   = 1 << ((PORT *)chan)->mp_SigBit;
    conmask = 1 << iocr->io_Message.mn_ReplyPort->mp_SigBit;

    iocr->io_Data = (APTR)&Cc;
    iocr->io_Length = 1;
    SendIO(iocr);

    setsize(iocw, chan);
    while (NotDone) {
	mask = Wait(imask|dmask|conmask);
	if (mask & imask) {
	    IMESS *im;
	    while (im = GetMsg(Win->UserPort)) {
		switch(im->Class) {
		case NEWSIZE:
		    setsize(iocw, chan);
		    break;
		case CLOSEWINDOW:
		    NotDone = 0;
		    break;
		case MENUPICK:
		    HandleMenu(im->Code);
		    break;
		}
		ReplyMsg(im);
	    }
	}
	if (mask & dmask) {
	    char buf[256];
	    int n, i;
	    if ((n = DNRead(chan, buf, 256)) > 0)
		for(i = 0; i < n;i++)
	/* check if tek wants the byte - if not just send it to window */
		    if(!Tek(buf[i])){
			iocw->io_Data = (APTR)&buf[i];
			iocw->io_Length = 1;
			DoIO(iocw);
		    }
	    if (n < 0)
		NotDone = 0;
	}
	if (mask & conmask)
	    if (CheckIO(iocr)) {
		WaitIO(iocr);
		DWrite(chan, &Cc, 1);
		iocr->io_Data = (APTR)&Cc;
		iocr->io_Length = 1;
		SendIO(iocr);
	    }
    }
    AbortIO(iocr);
    WaitIO(iocr);
    SetWindowTitles(Win, "Closing...", -1);
    DClose(chan);
    CloseTek();     /* closes and releases all the tek stuff */
e3: CloseConsole(iocr,iocw);
    CloseWindow(Win);
e1: CloseLibrary(IntuitionBase);
    CloseLibrary(GfxBase);
}

OpenConsole(win, piocr, piocw)
IOCON **piocr, **piocw;
WIN *win;
{
    PORT *port;
    static IOCON iocr, iocw;
    int error;

    port = CreatePort(NULL, 0);
    iocr.io_Command = CMD_READ;
    iocr.io_Data = (APTR)win;
    iocr.io_Message.mn_Node.ln_Type = NT_MESSAGE;
    iocr.io_Message.mn_ReplyPort = port;
    error = OpenDevice("console.device", 0, &iocr, 0);
    if (!error) {
	iocw = iocr;
	iocw.io_Command = CMD_WRITE;
	*piocr = &iocr;
	*piocw = &iocw;
    } else {
	*piocr = *piocw = NULL;
    }
}

CloseConsole(iocr, iocw)
IOCON *iocr;
IOCON *iocw;
{
    IOCON *tmp = (iocr) ? iocr : iocw;
    if (tmp) {
	CloseDevice(tmp);
	DeletePort(tmp->io_Message.mn_ReplyPort);
    }
}

setsize(iocw, chan)
IOCON *iocw;
long chan;
{
    struct ConUnit *cu = (struct ConUnit *)iocw->io_Unit;
/*    iocw->io_Data = (APTR)"\033c\033[20l\033[t\033[u";    */

    iocw->io_Data = (APTR)"\033[20l\033[t\033[u";
    iocw->io_Length = 11;
    DoIO(iocw);
    DIoctl(chan, CIO_SETROWS, cu->cu_YMax+1, 0);
    DIoctl(chan, CIO_SETCOLS, cu->cu_XMax+1, 0);
    sprintf(Term, "FTEK   %ld x %ld", cu->cu_YMax+1, cu->cu_XMax+1);
    SetWindowTitles(Win, Term, -1);
}

HandleMenu(code)
uword code;
{
	switch(MENUNUM(code)){
	    case 0:    /*	menu 0	*/
		switch(ITEMNUM(code)){
		    case 0:	/* item 0 */
			DIoctl(chan, CIO_FLUSH, 0, 0);
			break;
		    case 1:	/* item 1 */
			NotDone = 0; /* fall out of loop and quit */
			break;
		}
		break;
	    case 1:    /*	menu 1	*/
		switch(ITEMNUM(code)){
		    case 0:	/* item 0 -> choose tek scale */
			switch (SUBNUM(code)){
			    case 0: /* choose 1020x780 resolution */
				t_scale = 0;
				break;
			    case 1: /* choose 640x400 */
				t_scale = 1;
				break;
			}
			break;
		    case 1:	/* choose screen depth */
			switch (SUBNUM(code)) {
			    case 0:
				t_cmd_depth("1");
				break;
			    case 1:
				t_cmd_depth("2");
				break;
			    case 2:
				t_cmd_depth("3");
				break;
			    case 3:
				t_cmd_depth("4");
				break;
			}
			break;
		    case 2:		/* choose interlace */
			switch (SUBNUM(code)) {
			    case 0:
				t_cmd_interlace("0");
				break;
			    case 1:
				t_cmd_interlace("1");
				break;
			}
			break;
		}
		break;
	    case 2:    /* menu 2 */
		switch(ITEMNUM(code)){
		    case 0:		/* tek screen on/off */
			switch (SUBNUM(code)) {
			    case 0:	/* tek screen off  */
				t_cmd_on("0");
				break;
			    case 1:	/* tek screen on   */
				t_cmd_on("1");
				break;
			}
			break;
		    case 1:
			ScreenToFront(TekScreen); /* force tek screen to front */
			break;
		    case 2:
			ScreenToBack(TekScreen);  /* force vt screen to front */
			break;
		    case 3:		/* clear screen */
			if(Tek_screen_open == 1)
			    Tek(27);    /* put in escape mode */
			    Tek(12);    /* clear page */
			break;
		    case 4:		/* quit tekmode */
			TekMode = FALSE;
			break;
		}
		break;
	} /* end of switch (MENUNUM(code ) */
}
