V10/630/src/630mon.c

Compare this file to the similar file:
Show the results in this format:

#define MUXTERM
#define MPXTERM

#include "dmd.h"
#include "font.h"
#include "menu.h"
#include "defs.h"

#undef getname	/* strange hack to avoid name clash */

/* user nice sys queue idle */

Texture16 black={
	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	
	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	0xFFFF,	
};
Texture16 white={
	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
};
Texture16 darkgrey = {
	0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777,
	0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777,
};
Texture16 lightgrey = {
	0x2222, 0x8888, 0x2222, 0x8888, 0x2222, 0x8888, 0x2222, 0x8888,
	0x2222, 0x8888, 0x2222, 0x8888, 0x2222, 0x8888, 0x2222, 0x8888,
};
Texture16 grey = {
	0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555,
	0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555,
};

Texture16 *txt[]={
	&black, &lightgrey, &darkgrey, &grey, &white
};

#	define TIMELEN 6
char time[TIMELEN];
#	define NAMELEN 9
#	define LOADLEN 13
#	define MAILLEN 18

struct nodedef {
    Rectangle bar;		/* the bar graph of system use */
    char name[NAMELEN];		/* node name */
    char load[LOADLEN];		/* load numbers */
    int vec[5];			/* current use vectors */
    int oldvec[5];		/* old use vectors */
    char mail[MAILLEN];		/* last mail from this node */
};
struct nodedef node0;		/* preallocate node 0 */
int nodes = 0;			/* number of nodes */
struct nodedef *node[MAXMACHS] = {
	&node0
};

/* size contraints */
#define ICONSEP 2
#define BARHEIGHT 18
#define MINBARHEIGHT 4
#define MAXBARHEIGHT 24
#define TIMEORIGIN 2
int CHARHEIGHT;
int CHARWIDTH;
int TIMECORNER;
int LOADORIGIN;
int LOADCORNER;
int MAILORIGIN;
int MAILCORNER;

int size;
int barheight;
int iconorigin;

/* the communications process */
struct Proc *cwp;

/* icon info */
#define ICONSIZE 48
#define ICONWORDS (ICONSIZE*(ICONSIZE/16))
Bitmap *icon, *ticon;
int icons = 0;
int maxicons;
int haveicons = 0;

/* dynamically add/remove monitored systems */

static NMitem astroitems[] = {
	"alice",
	"arend",
	"bowell",
	"coma",
	"crab",
	"dutoit",
	"encke",
	"kwee",
	"panther",
	"pipe",
	"r70",
	"research",
	"seki",
	"spit",
	"swift",
	"west",
	"westphal",
	"wild",
	0
};

static NMenu astromenu = {astroitems};

static NMitem phoneitems[] = {
	{"atomic"},
	{"fry"},
	{"gauss"},
	{"shannon"},
	{"sid"},
	{0}
};

static NMenu phonemenu = {phoneitems};

static NMitem mercuryitems[] = {
	{"arachne"},
	{"balin"},
	{"bashful"},
	{"bifur"},
	{"capek"},
	{"doc"},
	{"eeyore"},
	{"gimli"},
	{"grumpy"},
	{"gunn"},
	{"happy"},
	{"hunny"},
	{"icarus"},
	{"indra"},
	{"iota"},
	{"jones"},
	{"kanga"},
	{"sapir"},
	{"siriusb"},
	{"sola"},
	{"sweet"},
	{"thorin"},
	{0}
};

static NMenu mercurymenu = {mercuryitems};

static NMitem machitems[] = {
	{"ca/xunet/fs"},
	{"nj/astro", 0, &astromenu},
	{"nj/garage/europa"},
	{"nj/mercury", 0, &mercurymenu},
	{"nj/phone", 0, &phonemenu},
	{"nj/vlsi/araki"},
	{"pa/ram/most"},
	{0}
};

NMenu nmenu2 = {machitems};

static struct {
	char *name;
	NMitem *base, *lim;
} menulist[] = {
	{"nj/astro/", astroitems, astroitems+sizeof(astroitems)/(sizeof(NMitem))-1},
	{"nj/mercury/", mercuryitems, mercuryitems+sizeof(mercuryitems)/(sizeof(NMitem))-1},
	{"nj/phone/", phoneitems, phoneitems+sizeof(phoneitems)/(sizeof(NMitem))-1},
	{0}
};


main()
{
	register i, state, hadmouse;


	request(RCV|MOUSE|KBD);

	CHARHEIGHT = defont.height - 2;
	CHARWIDTH = strwidth(&defont, "m");
	TIMECORNER = NAMELEN*CHARWIDTH;
	LOADORIGIN = TIMECORNER;
	LOADCORNER = TIMECORNER + LOADLEN*CHARWIDTH;
	MAILORIGIN = LOADCORNER;
	MAILCORNER = LOADCORNER + MAILLEN*CHARWIDTH;
	barheight = MAXBARHEIGHT;
	iconorigin = MAILCORNER;
	time[0] =  0;
	hadmouse = 0;

	for(;;sleep(3)){
		if (cwp != 0 && cwp->state == 0)
			cwp = 0;
		state = own();
		if(state&RCV)
			get();
		if(state&MOUSE) {
			if(button2()) {
				domenu();
			} else if(button3()) {
				request(RCV|KBD);
				sleep(1);
				request(RCV|KBD|MOUSE);
			} else if (!hadmouse || button1()) {
				clearmail();
				clearicon();
			}
		}
		hadmouse = state&MOUSE;
		if(state&KBD) {
			while(kbdchar() != -1)	/* dump any keyboard input */
				;
		}
		for (i = 0; i < nodes; i++)
			drawbar (node[i]);
		if(P->state&RESHAPED)
			reshape(0);
	}
}

reshape(msg)
	char *msg;
{
	register int i;

	P->state&=~RESHAPED;
	rectf(&display, Drect, F_CLR);

	/* output an error message */
	if (msg != 0) {
		string(&defont, msg, &display,
		Pt (Drect.origin.x+2, Drect.origin.y + 2), F_XOR);
		sleep(200);
		rectf(&display, Drect, F_CLR);
	}

	/* resize objects */
	size = Drect.corner.x-Drect.origin.x;
	barheight = (Drect.corner.y-Drect.origin.y-2)/(nodes?nodes:1) - CHARHEIGHT;
	if (barheight < MINBARHEIGHT)
		barheight = MINBARHEIGHT;
	if (haveicons) {
		if (barheight > MAXBARHEIGHT)
			barheight = MAXBARHEIGHT;
		i = 3*size/4;
		size = (i > MAILCORNER) ? MAILCORNER
					: ((i > LOADCORNER) ? LOADCORNER
							    : TIMECORNER);
		iconorigin = size;
		maxicons = (Drect.corner.x-Drect.origin.x-iconorigin)
			   / (ICONSIZE+ICONSEP);
	}

	/* redraw */
	for (i = 0; i < nodes; i++) {
		nodeinit(i);
		drawload(node[i]);
		drawmail(node[i]);
	};
	drawtime();
	clearmail();
	clearicon();
}


/* clear out the bar and write in the node name */
nodeinit (ind)
int ind;				/* index into node array */
{
	register struct nodedef *n;
	register int i;

	n = node[ind];

	/* make the bar */
	n->bar.origin.x = Drect.origin.x;
	n->bar.origin.y = Drect.origin.y + ind*(barheight+CHARHEIGHT);
	n->bar.corner.x = Drect.origin.x + size;
	n->bar.corner.y = n->bar.origin.y + barheight;
	n->bar = inset(n->bar, 4);
	rectf(&display, inset(n->bar, -2), F_OR);
	rectf(&display, n->bar, F_CLR);

	/* init the node */
	for(i = 0; i<4; i++)
		n->vec[i] = n->oldvec[i] = 0;
	n->vec[4]=n->oldvec[4]=size;

	/* write the name */
	if (ind != 0 && size >= TIMECORNER)
		string (&defont, n->name, &display, 
			Pt(TIMEORIGIN+Drect.origin.x, n->bar.origin.y+barheight-6),
			F_XOR);
};

domenu() {
	NMitem *mhit(), *sys;
	char name[48];

	sys = mhit(&nmenu2, 2, 0);
	if (sys) {
		register int i;
		strcpy(name, "M");
		for (i = 0; menulist[i].name; i++) {
			if (sys >= menulist[i].base && sys < menulist[i].lim) {
				strcat (name, menulist[i].name);
				break;
			}
		}
		strcat(name, sys->text);
		strcat(name, "\n");
		if (index (name, '/'))
			sendnchars(strlen(name), name);
	}
}


Point pt[4];
Rectangle new, old;

/* draw the bar graph for a system's CPU time */
drawbar (n)
struct nodedef *n;
{
	register i, now;

	pt[0].y = pt[2].y = n->bar.origin.y;
	pt[1].y = pt[3].y = n->bar.corner.y;
	new = old = n->bar;
	for(i=0; i<5; i++){
		now = relax(n->oldvec[i], n->vec[i]);
		old.corner.x = n->oldvec[i] + old.origin.x;
		new.corner.x = now+new.origin.x;
		sort(old.origin.x,old.corner.x, new.origin.x,new.corner.x);
		if (pt[3].x > n->bar.corner.x)
			pt[3].x = n->bar.corner.x;
		if (pt[1].x > n->bar.corner.x)
			pt[1].x = n->bar.corner.x;
		texture(&display, Rpt(pt[0], pt[1]), txt[i], F_XOR);
		texture(&display, Rpt(pt[2], pt[3]), txt[i], F_XOR);
		new.origin.x = new.corner.x;
		old.origin.x = old.corner.x;
		n->oldvec[i] = now;
	}
}

relax(o, n)
	int o, n;
{
	register a;
	register s=1;
	register long lo = o;
	register long ln = n;

	if(o>n)
		s= -1;
	a=abs(o-n);
	if(a<2)
		return n;
	if(a<127)
		return o+s;
	ln = (127L*lo + ln) / 128L;
	s = ln;

	return s;
}

sort(x)
	int x;
{
	register int *p= &x;
	register i,j;
	register t;
	for(i=0; i<3; i++){
		for(j=0; j<3; j++)
			if(p[j]>p[j+1]){
				t=p[j];
				p[j]=p[j+1];
				p[j+1]=t;
			}
	}
	for(i=0; i<4; i++)
		pt[i].x=p[i];
}

drawload(n)
	struct nodedef *n;
{
	if (size < LOADCORNER)
		return;
	string(&defont, n->load, &display, 
		Pt (Drect.origin.x+LOADORIGIN, n->bar.origin.y+barheight-6), F_XOR);
}

drawtime()
{
	if (size < TIMECORNER)
		return;
	string(&defont, time, &display,
		Pt (Drect.origin.x+TIMEORIGIN, Drect.origin.y+barheight-2), F_XOR);
}

drawmail(n)
	struct nodedef *n;
{
	if (size < MAILCORNER)
		return;
	string(&defont, n->mail, &display,
		Pt (Drect.origin.x+MAILORIGIN, n->bar.origin.y+barheight-6), F_XOR);
}

clearmail()
{
	register int i;

	for (i = 0; i < nodes; i++) {
		drawmail(node[i]);
		node[i]->mail[0] = '\0';
 	}
}

drawicon()
{
	Rectangle rect;
	Point to;
	int bltwidth, i;

	if (!haveicons || maxicons < 1)
		return;

	/* move icons right */
	bltwidth = (maxicons-1)*(ICONSIZE+ICONSEP) - ICONSEP;
	rect.origin.x = Drect.origin.x + iconorigin;
	rect.origin.y = Drect.origin.y + 2;
	rect.corner.x = rect.origin.x + bltwidth;
	rect.corner.y = rect.origin.y + ICONSIZE + 4 + CHARHEIGHT;
	to.x = rect.origin.x + ICONSIZE + ICONSEP;
	to.y = rect.origin.y;
	bitblt(&display, rect, &display, to, F_STORE);

	if (icons != maxicons)
		icons++;

	/* clear area */
	rect.corner.x = to.x;
	rectf(&display, rect, F_CLR);

	/* drop in new picture */
	to = rect.origin;
	rect = icon->rect;
	rect.origin.x += ICONSIZE/2;
	rect.origin.y += ICONSIZE/2;
	rect.corner.x -= ICONSIZE/2;
	rect.corner.y -= ICONSIZE/2;
	to.x += ICONSIZE/2;
	to.y += ICONSIZE/2;
	for (i=0; i<ICONSIZE/2; i++){
		rect.origin.x--;
		rect.origin.y--;
		rect.corner.x++;
		rect.corner.y++;
		to.x--;
		to.y--;
		bitblt(icon, rect, &display, to, F_STORE);
		sleep(2);
	}

	/* add a time stamp */
	to.y += ICONSIZE + 4;
	string(&defont, time, &display, to, F_XOR);
}

clearicon()
{
	Rectangle rect;

	if (!haveicons || maxicons < 1 || icons == 0)
		return;
	icons = 0;
	rect.origin.x = Drect.origin.x + iconorigin - 1;
	rect.origin.y = Drect.origin.y + 1;
	rect.corner.x = rect.origin.x + maxicons*(ICONSIZE+ICONSEP) - ICONSEP + 2;
	rect.corner.y = rect.origin.y + ICONSIZE + CHARHEIGHT + 6;
	rectf(&display, rect, F_CLR);
}

/* process a host message */
get(){
	register int ch;
	register struct nodedef *n;
	struct nodedef *nodeptr();

	ch = hostchar();
	if (ch == MAGIC_CH) {

		/* this is probably a message from the host half of sysmon */
		ch = hostchar();
		switch(ch){
		case 'V':
			while ((ch = hostchar()) != -1) {
				n = nodeptr(ch);
				getvec(n);
			}
			break;
		case 'L':
			while ((ch = hostchar()) != -1) {
				n = nodeptr(ch);
				drawload(n);
				getload(n);
				drawload(n);
			}
			break;
		case 'T':
			drawtime();
			gettime();
			drawtime();
			break;
		case 'M':
			n = nodeptr(hostchar());
			drawmail(n);
			getmail(n);
			drawmail(n);
			break;
		case 'I':
			geticon();
			drawicon();
			break;
		case 'N':
			getname();
			reshape(0);
			break;
		case 'Q':
			icon = balloc(Rect(0, 0, ICONSIZE, ICONSIZE));
			ticon = balloc(Rect(0, 0, ICONSIZE, ICONSIZE));
			if (!icon || !ticon) {
				reshape("Not enough memory for faces.");
				sendnchars(2, "R\n");		/* refuse faces */
				break;
			}
			sendnchars(2, "A\n");		/* accept faces */
			haveicons = 1;
			reshape(0);
			break;
		case 'R':
			remove(hostchar()-'0');
			reshape(0);
			break;
		case -1:
			return;
		default:
			writecw(ch);
			break;
		}
	} else {
		writecw(ch);
	}
	ignorerest();
}

struct nodedef *
nodeptr(c)
	int c;
{
	register i;

	i = c - '0';
	if (i < 0 || i >= nodes)
		i = 0;
	return node[i];
}

getvec(n)
	struct nodedef *n;
{
	register int i, sum, nsum, vec[5];

	for(sum=0,i=0; i<5; i++)
		sum += (vec[i] = hostchar());
	sum = sum ? sum : 1;
	for(nsum=0,i=0; i<4; i++)
		nsum += n->vec[i] = ((long)(vec[i])*size) / sum;
	n->vec[4]=size-nsum;
}

gettime()
{
	register char *p=time;
	register int c, i=0;

	while((c = hostchar()) != -1 && ++i < TIMELEN) 
		*p++ = c;
	*p=0;
}

getload(n)
	struct nodedef *n;
{
	register char *p=n->load;
	register int i=0;

	while((*p = hostchar()) != '\t' && ++i < LOADLEN)
		p++;
	*p=0;
}

getname()
{
	register char *p;
	register int c, i=0;

	if (nodes != 0) {
		node[nodes] = (struct nodedef *)alloc(sizeof (struct nodedef));
		if (!node[nodes]) {
			reshape("out of memory");
			sendnchars(2, "R\n");		/* refuse connection */
			return;
		}
	}
	sendnchars(2, "A\n");				/* accept connection */
	p = node[nodes]->name;
	while((c = hostchar()) != -1 && ++i < NAMELEN)
		*p++ = c;
	*p=0;
	nodes++;
}

remove(ind)
	register int ind;
{
	if (ind < 0 || ind >= nodes)
		return;
	free (node[ind]);
	for (; ind < nodes-1; ind++)
		node[ind] = node[ind+1];
	nodes--;
}

getmail(n)
	struct nodedef *n;
{
	register char *p=n->mail;
	register int c, i=0;

	while((c = hostchar()) != -1 && ++i < MAILLEN)
		*p++ = c;
	upfront(P->layer);
	ringbell ();
	*p=0;
}

geticon()
{
	register int c, i, j;
	register short *ip;

	/* once per scan line */
	ip = (short *)icon->base;
	for (i = 0; i < ICONSIZE; i++) {

		/* once per short */
		for (j = 0; j < ICONSIZE/16; j++) {
			c = hostchar();
			*ip = (c<<8) | hostchar();
#ifndef	mc68000
			if (VALSCREENCOLOR==0)
				*ip = ~*ip;
#endif mc68000
			ip++;
		}

#ifndef	mc68000
		/* blit and 5620 have different size bitmaps */
		ip++;
#endif mc68000
	}
}

int atend = 0;		/* non-zero if at end of message */

hostchar(){
	register int c;

	if (atend)
		return -1;

	if((c=rcvchar())==-1)
		wait(RCV), c=rcvchar();

	if (c == '\n') {

		/* newline's mark end of message */
		atend = 1;
		return -1;
	} else if (c == '\\') {

		/* backslashes are character escapes */
		if ((c=rcvchar())==-1)
			wait(RCV), c=rcvchar();
	}

	return c&0xff;
}

ignorerest()
{
	while (hostchar() != -1)
		;
	atend = 0;
}


#ifdef mc68000
ringbell ()
{
	*((char *)(384*1024L+062)) = 2;
}
#endif mc68000

/*
 *	The rest of jerqmon.c contains routines to create and update the
 *	communications window.
 */ 
#define	INSET	4
#define	C_NEW	2

makecw()
{
	register Rectangle r;
	register unsigned char *pout;

	/* first see if the process already exists */
	if (cwp != 0 && cwp->state != 0)
		return 0;
	else
		cwp = 0;

	/* create process */
	r = Drect;
	if(!(cwp=newproc((struct Proc *)0)))
		return -1;
	cwp->rect=inset(r, INSET);
	if( !rectclip(&cwp->rect,Jrect) || !(cwp->layer=newlayer(r))){
		cwp->state=0;
		return -1;
	}

	/* give it a window */
#ifndef mc68000
	muxnewwind(cwp, C_NEW);
#else
	mpxnewwind(cwp, C_NEW);
#endif mc68000

	/* wait for a prompt */
	pout = cwp->cbufpout;
	do sleep( 60 ); while( pout == cwp->cbufpout );
	ringbell();

	return 0;
}

/*
 *	Write a string to the communications window.  Create the
 *	window if it has disappeared.
 */
writecw(c)
	register int c;
{
	if (makecw() < 0) {
		drawmail(node[0]);
		getmail(node[0], "can't open comm window\n");
		drawmail(node[0]);
		return;
	}
	do {
		if (cwp->state) {
			upfront(cwp->layer);
			while (cwp->nchars < CBSIZE*3) {
				*(cwp->cbufpin++) = c != -1 ? c : '\n';
				cwp->nchars++;
				if (cwp->cbufpin >= &(cwp->cbuf[CBSIZE*3]))
					cwp->cbufpin = cwp->cbuf;
				if (c == -1)
					break;
				c = hostchar();
			}
			cwp->state |= WAKEUP;
			sleep (10);
		} else
			return;
	} while (c != -1);
}