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

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

#include "/server/servers.h"

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

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

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

MENU Menu[] = {
    { NULL    , 0, 0, 100, 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 *)"FTERM  Openning, Wait", NULL, NULL,
    32, 32, -1, -1, WBENCHSCREEN
};

WIN *Win;

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

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

long IntuitionBase;
long GfxBase;

main(ac,av)
char *av[];
{
    long chan;
    long n;
    long imask, conmask, dmask, mask;
    IOCON *iocr, *iocw;
    char notdone = 1;
    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;
    }
    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:
		    switch((uword)((MENUNUM(im->Code)<<8)|ITEMNUM(im->Code))) {
		    case 0x0000:    /*	menu 0 item 0	*/
			DIoctl(chan, CIO_FLUSH, 0, 0);
			break;
		    case 0x0001:    /*	menu 0 item 1	*/
		    case 0x0002:    /*	menu 0 item 2	*/
		    case 0x0100:    /*	menu 1 item 0	*/
			break;
		    }
		}
		ReplyMsg(im);
	    }
	}
	if (mask & dmask) {
	    char buf[256];
	    int n;
	    if ((n = DNRead(chan, buf, 256)) > 0) {
		iocw->io_Data = (APTR)buf;
		iocw->io_Length = n;
		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);
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;
{
    struct ConUnit *cu = (struct ConUnit *)iocw->io_Unit;

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

