Article: 629 of unix-pc.sources
From: mdapoz@hybrid.uucp (Mark Dapoz)
Newsgroups: unix-pc.sources,comp.sys.att
Subject: mgrload - an mgr client to graphically display the system load average
Keywords: mgr system load
Message-ID: <1990Jun22.055017.20122@hybrid.UUCP>
Date: 22 Jun 90 05:50:17 GMT
Sender: mdapoz@hybrid.UUCP (Mark Dapoz)
Organization: The Home for Unemployed Basselopes, Toronto, Ontario, Canada
Lines: 1589
Xref: icus unix-pc.sources:629 comp.sys.att:9601

Here's a little program I whipped up which is similar to the X windows client
xload, but written for specifically for mgr, enjoy..... mark

--- snip --- snip --- snip --- snip --- snip --- snip --- snip --- snip --- 

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by mdapoz@hybrid on Fri Jun 22 01:42:31 EDT 1990
# Contents:  README Makefile mgrload.c loadavgd.c term.h window.h mgrload.1
 
echo x - README
sed 's/^@//' > "README" <<'@//E*O*F README//'
Mgrload is a quick little program I wrote to imitate the function provided
by xload, the X windows load average monitor.  Full details of what mgrload
does can be found in the mgrload man page, however, be aware that mgrload
requires the loadavgd daemon to be running in the background, so remember
to start it (via root) before running mgrload.  As usual, bug reports/
ehancements/kudos/equipment/money :-) can be either posted to unix-pc.*, 
comp.sys.att or sent to directly to me.

		Mark Dapoz   90/06/21
		mdapoz@hybrid.UUCP  or
		mdapoz%hybrid@cs.toronto.edu
@//E*O*F README//
chmod u=rw,g=r,o=r README
 
echo x - Makefile
sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
# Makefile for mgrload
#	Mark Dapoz  90/06/21

CC	= cc
CFLAGS	= -O -DSYSV -DSAMPLES=120 -DINTERVAL=60 -DPSIZE=50
DEST	= /usr/local/bin
MGRLIB	= /usr/mgr/lib/libmgr.a

all: mgrload
	$(CC) $(LDFLAGS) mgrload.o -o mgrload $(MGRLIB)

mgrload: loadavgd mgrload.o

loadavgd: loadavgd.o
	$(CC) $(LDFLAGS) loadavgd.o -o loadavgd -lm

install: mgrload
	@if test `id | awk '{ FS="="; split($$2, n, "("); print n[1] }'` != "0" ; then echo "\n*** Must be root to install!"; exit 1 ; fi
	if test ! -d /etc/daemons ; then mkdir /etc/daemons ; fi
	/bin/cp loadavgd /etc/daemons
	/etc/daemons/loadavgd
	/bin/cp mgrload $(DEST)
	/bin/cp mgrload.1 /usr/man/man1

shar:
	shar -b -c -t -v README Makefile mgrload.c loadavgd.c \
		term.h window.h mgrload.1 > mgrload.shar

clean: 
	/bin/rm mgrload.o mgrload loadavgd.o loadavgd

clobber: clean
@//E*O*F Makefile//
chmod u=rw,g=r,o=r Makefile
 
echo x - mgrload.c
sed 's/^@//' > "mgrload.c" <<'@//E*O*F mgrload.c//'
/*
   mgrload - show cpu load average in an mgr window.  Requires accompanying
	     loadavgd daemon for sysinfo data extraction from kernel.

	     Mark Dapoz  90/06/21
		mdapoz@hybrid.UUCP or 
		mdapoz%hybrid@cs.toronto.edu
*/

#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/utsname.h>
#include "term.h"

#ifndef	SAMPLES
#define	SAMPLES		120	/* number of samples to keep */
#endif
#ifndef	INTERVAL
#define	INTERVAL	60	/* time interval (sec) between samples*/
#endif
#ifndef	PSIZE
#define	PSIZE		50	/* size of one display partition; .50 proc */
#endif

#define	XHOME		20	/* default location and size of display */
#define	YHOME		295
#define	XSIZE		300
#define	YSIZE		50

#define	CONTEXT P_POSITION | P_WINDOW | P_FLAGS | P_EVENT | P_CURSOR | P_MENU

int xscale, yscale, rscale;
int xmin, xmax, ymin, ymax;
int width;
char *version = "Version 1.0  90/06/21";

main(argc,argv)
int argc;
char **argv;
{
	int xhome=XHOME, yhome=YHOME; /* window position */
	int xsize=XSIZE, ysize=YSIZE; /* window size */
	int erropt=0;
	int samples[SAMPLES];		/* circular queue of samples */
	int head=0;			/* queue pointer */
	int partitions, last_part=0;
	char event[80], c;		/* mgr event queue */
	int timer_event(), done();	/* mgr event handlers */
	register int i;
	int shm;			/* sysinfo shared segment */
	double *shmseg;
	char *options, scale[16], stats[16*3], 
	     hostname[sizeof(struct utsname)+32];
	struct utsname unixname;
	extern char *optarg;

	ckmgrterm(*argv);	/* check if an mgr terminal */
				/* process command line options */
	while ((c=getopt(argc, argv, "x:y:l:w:")) != EOF)
	    switch (c) {
		case 'x':	/* x co-ordinate location */
			if (strspn(optarg, "0123456789") == strlen(optarg))
			    xhome=atoi(optarg);
			else
			    erropt++;
			break;
		case 'y':	/* y co-ordinate location */
			if (strspn(optarg, "0123456789") == strlen(optarg))
			    yhome=atoi(optarg);
			else
			    erropt++;
			break;
		case 'l':	/* window length */
			if (strspn(optarg, "0123456789") == strlen(optarg))
			    xsize=atoi(optarg);
			else
			    erropt++;
			break;
		case 'w':	/* window width */
			if (strspn(optarg, "0123456789") == strlen(optarg))
			    xsize=atoi(optarg);
			else
			    erropt++;
			break;
		case '?':	/* unknown option */
			erropt++;
	    }
	if (erropt) {
	    fprintf(stderr, "usage: %s [-x nn] [-y nn] [-l nn] [-w nn]\n",
		argv[0]);
	    exit(1);
	}
	memset(samples, 0, SAMPLES);
	xmin = 0;	/* mgr virtual window size */
	ymin = 0;
	xmax = 999;
	ymax = 999;
	xscale = xmax-xmin;
	yscale = ymax-ymin;
	width=xscale/SAMPLES; /* width of one bar */

		/* find loadavgd segment */
	if ((shm = shmget(ftok("/unix",'a'),12,0)) < 0) {
	    perror("unable to attach sysinfo shared segment");
	    exit(1);
	}
	if (uname(&unixname) < 0) { /* get system info */
	    perror("unable to get system name");
	    exit(1);
	}
	m_setup(0);		/* init mgr */
	m_push(CONTEXT); /* save window settings */
	m_setcursor(CS_INVIS); /* get rid of cursor */
	m_ttyset(); /* setup communication channel */
				/* setup system interrupts */
	signal(SIGALRM, timer_event); /* sampling interrupt */
	signal(SIGTERM, done); /* exit */
	signal(SIGINT, done); /* exit */
	signal(SIGQUIT, done); /* exit */
	signal(SIGHUP, done); /* exit */
				/* setup mgr events */
	m_setevent(ACTIVATE,  "A\r");
	m_setevent(COVERED,   "C\r");
	m_setevent(UNCOVERED, "U\r");
	m_setevent(RESHAPE,   "H\r");
	m_setevent(REDRAW,    "R\r");

	m_shapewindow(xhome, yhome, xsize, ysize); /* resize window */
	m_func(B_SET);		/* set drawing mode on */
	m_clear(); m_flush();	/* clear screen */
	m_sendme("S\r"); /* sample load average event */
				/* setup menus */
	options="|stats ->|scale ->|refresh|reset|||R\r|X\r|";
	m_loadmenu(1, options); /* top level options */
	sprintf(scale, "|top = %3.2f||", 0.0); /* current scale */
	m_loadmenu(2, scale); /* load second level menu */
	m_linkmenu(1, 1, 2, MF_AUTO); /* link to main menu */
	sprintf(stats, "|max = %3.2f|min = %3.2f||", 0.0, 0.0);
	sprintf(stats,"|max  = %3.2f|min  = %3.2f|last = %3.2f||||",
		 0.0, 0.0, 0.0);
	m_loadmenu(3, stats); 
	m_linkmenu(1, 0, 3, MF_AUTO); /* link stats to main menu */
	m_selectmenu2(1); /* bind menu to right button */
	sprintf(hostname, "|%s|%s %s %s %s|mgrload %s||||", unixname.nodename,
	    unixname.sysname, unixname.release, unixname.version,
	    unixname.machine, version);
	m_loadmenu(10, hostname);
	m_selectmenu(10); /* bind host info to middle button */
	for(;;) {
	    if (m_gets(event) == NULL)
		if (errno = EINTR) /* restart interrupted call */
		    continue;
		else
		    break; /* exit */
	    switch (*event) {
		case 'A':	/* window activated */
		case 'C':	/* window covered */
		case 'U':	/* window uncovered */
		    break;
		case 'X':	/* reset stored samples */
		    memset(samples, 0, SAMPLES);
		    head=0;
		    m_sendme("R\rS\r"); /* force redraw and sample */
		    break;
		case 'R':	/* redraw window */
		case 'H':	/* reshape window */
		    m_func(B_SET);
		    m_clear();
		    redraw(samples, head-1 < 0 ? SAMPLES-1 : head-1);
		    draw_scale(partitions, 0, 999);
		    break;
		case 'S':	/* get load average */
		    shmseg = (double *)shmat(shm, (char *) 0, SHM_RDONLY);
		    samples[head]=(int)(shmseg[0]*100); /* 1 min avg */
		    shmdt(shmseg);
		    partitions=max(samples)/PSIZE+1;
		    sprintf(stats,"|max  = %3.2f|min  = %3.2f|last = %3.2f||||",
			max(samples)/100.0, min(samples)/100.0, 
			samples[head]/100.0);
		    m_loadmenu(3, stats); /* update pop up menu info */
		    rscale=partitions*PSIZE;
		    if (last_part == partitions) { /* fit on last scale? */
			m_func(B_COPY);	/* set copy mode */
/*
			m_bitcopy(width, 0, 1000-width, 1000, 0, 0);
*/
			m_bitcopy(width, 0, 1000, 1000, 0, 0);
			m_func(B_CLEAR);	/* set clear mode */
			m_bitcopy(0, 0, width, 1000, 0, 0);/* clear a column*/
			m_func(B_SET);	/* set drawing mode on */
			for (i=0; i < width; i++) /* draw bar */
			    m_line(i,ymax, i, ymax-samples[head]*yscale/rscale);
			draw_scale(partitions, 0, width-1);
		    } else { /* change scale */
			sprintf(scale, "|top = %3.2f||",partitions*PSIZE/100.0);
			m_loadmenu(2, scale); /* update pop up menu info */
			last_part=partitions;
			m_clear();
			redraw(samples, head);
			draw_scale(partitions, 0, 999);
		    }
		    m_flush();
		    head++;head%=SAMPLES;
		    alarm(INTERVAL);
		    break;
		default:
		    break;
	    }
	}
}

int max(nums) /* find maximum load avarage in queue */
int *nums;
{
	static int i,j;

	for (i=j=0; i < SAMPLES; nums++, i++)
	    j=*nums > j ? *nums : j;
	return(j);
}

int min(nums) /* find minimum load avarage in queue */
int *nums;
{
	static int i,j;

	for (i=0,j=99999; i < SAMPLES; nums++, i++)
	    j=*nums && *nums < j ? *nums : j; /* ignore zero values */
	return(j);
}

draw_scale(sections, left, right) /* draw scale lines on the graph */
int sections;
int left,right;
{
	int i,j;

	m_func(B_XOR);	/* invert pixels for scale */
	for (i=1; i < sections; i++) { /* draw scale lines */
	    j=ymax-i*PSIZE*yscale/rscale;
	    m_line(left, j, right, j);
	}
	m_flush();
}

redraw(nums, head) /* redraw graph from history */
int *nums;
int head;
{
	register int i,j,p;

	m_func(B_SET);	/* draw on */
	for (p=SAMPLES-1, j=head+1; p >= 0; p--) {
	    j=j%SAMPLES; /* wrap? */
	    if (nums[j]) /* a value? */
		for (i=0; i < width; i++) /* draw bar */
		    m_line(p*width+i, ymax, 
			   p*width+i, ymax-nums[j]*yscale/rscale);
	    j++;
	}
}

timer_event() /* cause the load average to be sampled */
{
    m_sendme("S\r"); /* sample load average event */
    signal(SIGALRM, timer_event);
}

done() /* general purpose exit */
{
    m_ttyreset(); /* reset communication channel */
    m_popall(); /* restore window */
    exit(0);
}
@//E*O*F mgrload.c//
chmod u=rw,g=r,o=r mgrload.c
 
echo x - loadavgd.c
sed 's/^@//' > "loadavgd.c" <<'@//E*O*F loadavgd.c//'
/*
 * renamed loadavgd.c by Lenny Tropiano (lenny@icus.UUCP ICUS Software Systems)
 *
 *	ldavg.c -- compute load averages for System V
 *	Phil Budne @ Boston U / DSG
 *
 *	Forges BSD 4.2 rwhod packets containing system load averages
 *	(#ifdef RWHOD for this, else a shm segment is used, ftok("/unix", 'a'))
 */

# include <sys/types.h>			/* system types */
# include <sys/sysinfo.h>		/* sysinfo structure */
# include <sys/utsname.h>		/* for uname(2) */
# include <sys/stat.h>			/* for stat(2) */
# include <sys/param.h>			/* for HZ */
# include <stdio.h>
# include <nlist.h>
# include <time.h>
# include <math.h>
# include <utmp.h>
# include <fcntl.h>
#ifdef RWHOD
# include "rwhod.h"			/* (from BSD) */
#else  SHM
# include <sys/ipc.h>
# include <sys/shm.h>
#endif RWHOD

/* # define DEBUG /**/
#ifdef RWHOD
# define UDP 1
# define DSK 1
# define PMUL 100

# if UDP
# include "netdb.h"
unsigned short port = 513;
unsigned long ipaddr;
# endif
#endif RWHOD

extern struct utmp *getutent();

# define UNIX "/unix"
# define KMEM "/dev/kmem"

struct nlist nlsym[] = {
# define NL_SYSINFO 0
        { "sysinfo" },			/* 0 */
#ifdef RWHOD
# define NL_LBOLT 1
	{ "lbolt" },			/* 1 */
#endif RWHOD
        { 0 }
};

#ifdef RWHOD
struct whod proto;
struct utsname utsn;
char whopacket[100];
#else  SHM
key_t aven_key;
int aven_shm;
double *aven_seg;
#endif RWHOD
int fd, memfd;

char *unixsys = UNIX;
char *kmem = KMEM;
char *argv0;

main(argc, argv)
int  argc;
char *argv[];
{
	switch (fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		break;
	default:
		exit(0);
	}
	argv0 = argv[0];
#ifdef RWHOD
	uname(&utsn);			/* get system names */
#endif RWHOD
	setpgrp();			/* create own pgrp */
	init_nlist();			/* get name values, open kmem */
	init_packet();			/* initialize packet prototype */
	doit();				/* never returns */
} /* main */

init_nlist() {
	nlist(unixsys, nlsym);		/* get system values */

        if(nlsym[NL_SYSINFO].n_value == 0) {
                fprintf(stderr, "%s: can't find sysinf structure\n", argv0);
                exit(1);
        } /* no value */

	if ((memfd = open(kmem, O_RDONLY)) < 0) {
		fprintf(stderr, "%s: no mem\n", argv0);
		exit(1);
	} /* could not open kmem */

} /* init_nlist */

# define PERIOD 5			/* sample period (in seconds) */
# define INTERVAL1 60			/* average interval 1 (in seconds) */
# define INTERVAL2 (5*60)		/* average interval 2 (in seconds) */
# define INTERVAL3 (15*60)		/* average interval 3 (in seconds) */
# define PACKINTERVAL 30		/* interval for make_packet */

doit() {
	struct sysinfo sinf;
	int packt = 0;
	long occ, que, nocc, nque, n, c;
	double avg1, avg2, avg3, new;
	double exp1, exp2, exp3;

	exp1 = exp( - ((double) PERIOD) / INTERVAL1 );
	exp2 = exp( - ((double) PERIOD) / INTERVAL2 );
	exp3 = exp( - ((double) PERIOD) / INTERVAL3 );

	getsysinf(&sinf);		/* prime the pump */
	occ = sinf.runocc;		/* number of samples */
	que = sinf.runque;		/* run queue summation */

	avg1 = avg2 = avg3 = ((double) que) / occ;

	for( ; ; ) {
		if( --packt < 0 ) {
#ifdef RWHOD
			make_packet((int) (avg1 * PMUL),
				    (int) (avg2 * PMUL),
				    (int) (avg3 * PMUL));
#else  SHM
			make_packet(avg1, avg2, avg3);
#endif RWHOD
			packt = PACKINTERVAL / PERIOD;
		} /* packet time */

/*		printf("runque: %ld  runocc: %ld\n", que, occ ); /**/

		sleep(PERIOD);
		getsysinf(&sinf);	/* get new info */
		nocc = sinf.runocc;
		nque = sinf.runque;

		n = nocc - occ;		/* get number of times updated */
		if( n <= 0 ) continue;
		c = nque - que - n;	/* get number of runners w/o us */
		if( c < 0 ) c = 0;	/* mumble! */

		new = ((double) c ) / n; /* new instantaneous avg */

		/************************************************/
		/*   The following formula is used to achieve   */
		/*   exponential decay of old measurements:	*/
		/*	avgN = avgN * expN  +  new * (1 - expN)	*/
		/*						*/
		/*   However, the factorized forms below	*/
		/*   require fewer floating point operations.	*/
		/************************************************/

		avg1 = ((avg1 - new) * exp1) + new;
		avg2 = ((avg2 - new) * exp2) + new;
		avg3 = ((avg3 - new) * exp3) + new;

		occ = nocc;
		que = nque;

	} /* for ever */
} /* doit */

getsysinf(s)
struct sysinfo *s;
{
	l_lseek(memfd, (long)nlsym[NL_SYSINFO].n_value, 0);
	r_read(memfd, (char *)s, sizeof(struct sysinfo));
}

/* lseek with error checking */
l_lseek(fd, offset, whence)
int fd, whence;
long	offset;
{
	if (lseek(fd, offset, whence) == -1) {
		fprintf(stderr, "%s: error on lseek\n", argv0);
		exit(1);
	}
}

/* read with error checking */
r_read (fd, buf, nbytes)
int	fd, nbytes;
char	*buf;
{
	if (read(fd, buf, nbytes) != nbytes) {
		fprintf(stderr, "%s: error on read\n", argv0);
		exit(1);
	}
}

init_packet() {
#ifdef RWHOD
	time_t boothz;
# if UDP
	struct hostent *he;

	he = gethostbyname( "localnet" );
	if( he == NULL || he->h_addr == 0 ) {
		fprintf(stderr, "no address: localnet\n");
		exit( 1 );
	}
	ipaddr = he->h_addr;
# endif
# if DSK
	sprintf(whopacket, "/usr/spool/rwho/whod.%s", utsn.nodename);
# endif
	memset(&proto, '\0', sizeof proto);	/* clear proto packet */

	strncat(proto.wd_hostname, utsn.nodename, 9); /* at most 9, add null */
	proto.wd_vers = WHODVERSION;
	proto.wd_type = WHODTYPE_STATUS;

	l_lseek(memfd, (long)nlsym[NL_LBOLT].n_value, 0);
	r_read(memfd, (char *)&boothz, sizeof( boothz ) );
	proto.wd_boottime = time(0) - (boothz / HZ);
#else  SHM
	if ((aven_key = ftok(UNIX, 'a')) == (key_t) -1) {
		perror(UNIX);
		exit(1);
	}
	if ((aven_shm = shmget(aven_key, 3 * sizeof (double), IPC_CREAT|IPC_EXCL|0644)) < 0) {
		perror("shmget");
		exit(1);
	}
	if ((int) (aven_seg = (double *) shmat(aven_shm, (char *) 0, 0)) == -1) {
		perror("shmat");
		if (shmctl(aven_shm, IPC_RMID, (struct shmid_ds *) 0) < 0)
			perror("shmctl(IPC_RMID)");
		exit(1);
	}
#endif RWHOD
	
} /* init_packet */

make_packet(iavg1, iavg2, iavg3)
#ifdef RWHOD
long iavg1, iavg2, iavg3;
#else  SHM
double iavg1, iavg2, iavg3;
#endif RWHOD
{
#ifdef RWHOD
	static struct whod packet;	/* local packet copy */
	register struct whoent *wep;	/* pointer to packet whoent */
	register struct utmp *utp;	/* return from getutent */
	int whof, cc;			/* output file, char count */

	packet = proto;			/* copy proto packet */
	time(&packet.wd_sendtime);
	time(&packet.wd_recvtime);	/* forge this !! */
	packet.wd_loadav[0] = iavg1;
	packet.wd_loadav[1] = iavg2;
	packet.wd_loadav[2] = iavg3;

	setutent();			/* open utmp file */
	wep = &packet.wd_we[0];		/* get pointer to first user in pkt */

	while( (utp = getutent()) != NULL ) {
	    if( (utp->ut_type == USER_PROCESS) && utp->ut_user[0]) {
		strncpy(wep->we_utmp.out_line, utp->ut_id, 4);
		wep->we_utmp.out_line[4] = '\0';

		strncpy(wep->we_utmp.out_name, utp->ut_user, 8);

		wep->we_utmp.out_time = utp->ut_time;

		wep->we_idle = idletime(utp);
		wep++;			/* bump packet pointer */
	    } /* user process */
	} /* while */
	endutent();

# if DSK
	whof = creat(whopacket, 0644);	/* open packt file */
	if( whof >= 0 ) {
	    cc = (char *)wep - (char *)&packet;
	    if( write(whof, (char *)&packet, cc) != cc )
	    	perror("write failed");
	    close(whof);
	} /* file opened */
	else perror(whopacket);
# endif
# if UDP
	cc = (char *)wep - (char *)&packet;
	udpsend( (char *)&packet, cc, ipaddr, port, port, 1);
# endif
# ifdef DEBUG
	fprintf(stderr, "wrote packet (%d)\n", cc);
	fflush(stderr);
# endif
#else  SHM
	aven_seg[0] = iavg1;
	aven_seg[1] = iavg2;
	aven_seg[2] = iavg3;
#endif RWHOD
} /* make_packet */

#ifdef RWHOD
idletime(up)
struct utmp *up;
{
    register int i;
    register char *cp, *dp;
    char ttyname[10];
    struct stat buf;
    time_t now;

    cp = "/dev/";
    dp = ttyname;
    
    while( *cp != '\0' )		/* copy "/dev/" */
        *dp++ = *cp++;

    cp = up->ut_line;			/* get line name */
    if( *cp == 's' )			/* starts with an 's'? (sxtnnn) */
        *dp++ = 'v';			/* insert a 'v' */

    for( i = 0; i < 8; i++ )		/* copy line name */
        if( (*dp++ = *cp++) == '\0' ) break;	/* or until null */

    if( stat(ttyname, &buf) != 0 )	/* get file status */
        return( 0 );

    time(&now);				/* get current time */
    i = now - buf.st_atime;		/* get differnce from last acces */
    return( i );			/* return idle time */
} /* idletime */
#endif RWHOD
@//E*O*F loadavgd.c//
chmod u=rw,g=r,o=r loadavgd.c
 
echo x - term.h
sed 's/^@//' > "term.h" <<'@//E*O*F term.h//'
/*                        Copyright (c) 1987 Bellcore
 *                            All Rights Reserved
 *       Permission is granted to copy or use this program, EXCEPT that it
 *       may not be sold for profit, the copyright notice must be reproduced
 *       on copies, and credit should be given to Bellcore where it is due.
 *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
 */
/*	$Header: term.h,v 4.6 88/08/18 10:17:05 sau Exp $
	$Source: /tmp/mgrsrc/lib/RCS/term.h,v $
*/
static char	h_term_[] = "$Source: /tmp/mgrsrc/lib/RCS/term.h,v $$Revision: 4.6 $";

/* macros for writing to mgr terminal emulator */

#ifndef _TERM_INCL
#define _TERM_INCL

#include "window.h"

#ifndef stderr
#include <stdio.h>
#endif
 
#ifndef ECHO
#ifdef SYSV
#include <termio.h>
#else
#include <sgtty.h>
#endif
#endif

#define TTYMAX		10	/* stack size for ttyset() */

#define M_FLUSH		0x1	/* autoflush output after each write */
#define M_DEBUG		0x2	/* use stderr instead of /dev/tty mgr i/o */
#define M_MODEOK	0x4	/* assume tty modes are always ok */

#ifndef M_DEVICEIN
#define M_DEVICEIN	"/dev/tty"
#endif

#ifndef M_DEVICEOUT
#define M_DEVICEOUT	"/dev/tty"
#endif


#define m_flush()		fflush(m_termout)

#define BTWN(a,x,b)	\
	((x)<(a)?a:(x)>(b)?b:x)
#define LIMIT(x)	BTWN(0,x,1152)

#ifndef M_NOFLUSH
#define _m_flsh		,(m_flags&M_FLUSH?m_flush():m_flags)
#else
#define _m_flsh
#endif

/* vi-like stuff */

#define m_addline() \
	(fprintf(m_termout,"%c%c",m_escchar,E_ADDLINE)_m_flsh)

#define m_addlines(n) \
	(fprintf(m_termout,"%c%d%c",m_escchar,n,E_ADDLINE)_m_flsh)

#define m_addchar() \
	(fprintf(m_termout,"%c%c",m_escchar,E_ADDCHAR)_m_flsh)

#define m_addchars(n) \
	(fprintf(m_termout,"%c%d%c",m_escchar,n,E_ADDCHAR)_m_flsh)

#define m_deleteline() \
	(fprintf(m_termout,"%c%c",m_escchar,E_DELETELINE)_m_flsh)

#define m_deletelines(n) \
	(fprintf(m_termout,"%c%d%c",m_escchar,n,E_DELETELINE)_m_flsh)

#define m_deletechar() \
	(fprintf(m_termout,"%c%c",m_escchar,E_DELETECHAR)_m_flsh)

#define m_deletechars(n) \
	(fprintf(m_termout,"%c%d%c",m_escchar,n,E_DELETECHAR)_m_flsh)

#define m_standend() \
	(fprintf(m_termout,"%c%c",m_escchar,E_STANDEND)_m_flsh)

#define m_standout() \
	(fprintf(m_termout,"%c%c",m_escchar,E_STANDOUT)_m_flsh)

#define m_bell() \
	(fprintf(m_termout,"\007")_m_flsh)

#define m_setcursor(n) \
	(fprintf(m_termout,"%c%d%c",m_escchar,n,E_SETCURSOR)_m_flsh)

/* lines */

/*
#define m_line(x0,y0,x1,y1) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c",m_escchar, \
	LIMIT(x0),LIMIT(y0),LIMIT(x1),LIMIT(y1),E_LINE)_m_flsh)
*/

#define m_line(x0,y0,x1,y1) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c",m_escchar, \
	x0,y0,x1,y1,E_LINE)_m_flsh)

#define m_lineto(to,x0,y0,x1,y1) \
	(fprintf(m_termout,"%c%d,%d,%d,%d,%d%c",m_escchar, \
	x0,y0,x1,y1,to,E_LINE)_m_flsh)

#define m_draw(x,y) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar, \
	LIMIT(x),LIMIT(y),E_LINE)_m_flsh)

#define m_fastdraw(x,y,count,buff) \
	(fprintf(m_termout,"%c%d,%d,%d%c",m_escchar, \
	LIMIT(x),LIMIT(y),count,E_GRUNCH), \
	fwrite(buff,1,count,m_termout)_m_flsh)

#define m_rfastdraw(count,buff) \
	(fprintf(m_termout,"%c%d%c",m_escchar, \
	count,E_GRUNCH), \
	fwrite(buff,1,count,m_termout)_m_flsh)

#define m_aligntext() \
	(fprintf(m_termout,"%c%c",m_escchar, \
	E_LINE)_m_flsh)

#define m_gotext() \
	(fprintf(m_termout,"%c%c",m_escchar, \
	E_GO)_m_flsh)

#define m_go(x,y) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar, \
	LIMIT(x),LIMIT(y),E_GO)_m_flsh)

/* bitblits */

#define m_clear() \
	(fprintf(m_termout,"%c",C_FF)_m_flsh)

#define m_func(func)\
	(fprintf(m_termout,"%c%d%c",m_escchar,func,E_BITBLT)_m_flsh)

#define m_bitwrite(x,y,w,h) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c",m_escchar,x,y,w,h,E_BITBLT)_m_flsh)

#define m_bitwriteto(x,y,w,h,to) \
	(fprintf(m_termout,"%c%d,%d,%d,%d,%d%c", \
	m_escchar,x,y,w,h,to,E_BITBLT)_m_flsh)

#define m_bitcopy(xd,yd,w,h,xs,ys) \
	(fprintf(m_termout,"%c%d,%d,%d,%d,%d,%d%c", \
	m_escchar,xd,yd,w,h,xs,ys,E_BITBLT)_m_flsh)

#define m_bitcopyto(xd,yd,w,h,xs,ys,to,from) \
	(fprintf(m_termout,"%c%d,%d,%d,%d,%d,%d,%d,%d%c", \
	m_escchar,xd,yd,w,h,xs,ys,to,from,E_BITBLT)_m_flsh)

#define m_bitld(w,h,x,y,size) \
	(fprintf(m_termout,"%c%d,%d,%d,%d,%d%c",\
	m_escchar,w,h,x,y,size,E_BITLOAD),m_flush())

#define m_bitldto(w,h,x,y,to,size) \
	(fprintf(m_termout,"%c%d,%d,%d,%d,%d,%d%c",\
	m_escchar,w,h,x,y,to,size,E_BITLOAD),m_flush())

#define m_bitdestroy(n) \
	(fprintf(m_termout,"%c%d%c",\
	m_escchar,n,E_BITCRT),m_flush())

#define m_bitcreate(n,w,h) \
	(fprintf(m_termout,"%c%d,%d,%d%c",\
	m_escchar,n,w,h,E_BITCRT),m_flush())

#define m_bitget(from,size,offset) \
	(fprintf(m_termout,"%c%d,%d,%d%c",\
	m_escchar,from,size,offset,E_BITGET),m_flush())
 
#define m_othersave(id,sub,name) \
	(fprintf(m_termout,"%c%d,%d,%d%c%s",\
	m_escchar,id,sub,strlen(name),E_SMAP,name)_m_flsh)
 
#define m_windowsave(name) \
	(fprintf(m_termout,"%c%d%c%s",\
	m_escchar,strlen(name),E_SMAP,name)_m_flsh)
 
#define m_bitsave(from,name) \
	(fprintf(m_termout,"%c%d,%d%c%s",\
	m_escchar,from,strlen(name),E_SMAP,name)_m_flsh)
 
#define m_bitfromfile(to,name) \
	(fprintf(m_termout,"%c%d,%d%c%s",\
	m_escchar,to,strlen(name),E_GMAP,name)_m_flsh)
 
#define m_highlight(x,y,w,h) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c",\
	m_escchar,x,y,w,h,E_BLEEP),m_flush())
 
#define m_stringto(to,x,y,text) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c%s",\
	m_escchar,to,x,y,strlen(text),E_STRING,text)_m_flsh)

/* other graphic functions */

#define m_circle(x,y,r) \
	(fprintf(m_termout,"%c%d,%d,%d%c",m_escchar, \
	LIMIT(x),LIMIT(y),LIMIT(r),E_CIRCLE)_m_flsh)

#define m_ellipse(x,y,r1,r2) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c",m_escchar, \
	LIMIT(x),LIMIT(y),LIMIT(r1),LIMIT(r2),E_CIRCLE)_m_flsh)

#define m_arc(x,y,x1,y1,x2,y2) \
	(fprintf(m_termout,"%c%d,%d,%d,%d,%d,%d%c",m_escchar, \
	LIMIT(x),LIMIT(y),LIMIT(x1),LIMIT(y1),LIMIT(x2),LIMIT(y2), \
	E_CIRCLE)_m_flsh)

#define m_ellipseto(to,x,y,r1,r2) \
	(fprintf(m_termout,"%c%d,%d,%d,%d,%d%c",m_escchar, \
	LIMIT(x),LIMIT(y),LIMIT(r1),LIMIT(r2),to,E_CIRCLE)_m_flsh)

#define m_rcircle(r) \
	(fprintf(m_termout,"%c%d%c",m_escchar, \
	LIMIT(r),E_CIRCLE)_m_flsh)

#define m_rellipse(r1,r2) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar, \
	LIMIT(r1),LIMIT(r2),E_CIRCLE)_m_flsh)


#define m_movemouse(x,y) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,x,y,E_MOUSE)_m_flsh)

#define m_movecursor(x,y) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,x,y,E_MOVE)_m_flsh)

#define m_move(col,row) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,col,row,E_CUP)_m_flsh)

#define m_moveprint(x,y,str) \
	(fprintf(m_termout,"%c%d,%d%c%s",m_escchar,x,y,E_MOVE,str)_m_flsh)

#define m_incr(x) \
	(fprintf(m_termout,"%c%d%c",m_escchar,x,E_MOVE)_m_flsh)

#define m_cleareol() \
	(fprintf(m_termout,"%c%c",m_escchar,E_CLEAREOL)_m_flsh)

#define m_cleareos() \
	(fprintf(m_termout,"%c%c",m_escchar,E_CLEAREOS)_m_flsh)

/* window manipulation */

#define m_movewindow(x,y) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,x,y,E_SHAPE)_m_flsh)

#define m_shapewindow(x,y,dx,dy) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c",m_escchar,x,y,dx,dy,E_SHAPE)_m_flsh)

#define m_font(x) \
	(fprintf(m_termout,"%c%d%c",m_escchar,x,E_FONT)_m_flsh)

#define m_loadfont(n,name) \
	(fprintf(m_termout,"%c%d,%d%c%s", \
	m_escchar,n,strlen(name),E_FONT,name)_m_flsh)

#define m_size(cols,rows) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,cols,rows,E_SIZE)_m_flsh)

#define m_sizeall(x,y,cols,rows) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c", \
         m_escchar,x,y,cols,rows,E_SIZE)_m_flsh)

#define m_scrollregion(first,last) \
	(fprintf(m_termout,"%c%d,%d%c", \
	m_escchar,first,last,E_TEXTREGION)_m_flsh)

#define m_textregion(x,y,wide,high) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c", \
	m_escchar,x,y,wide,high,E_TEXTREGION)_m_flsh)

#define m_textreset() \
	(fprintf(m_termout,"%c%c",m_escchar,E_TEXTREGION)_m_flsh)

/* window creation/ destruction */

#define m_newwin(x,y,w,h) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c",m_escchar,x,y,w,h,E_MAKEWIN)_m_flsh)

#define m_destroywin(n) \
	(fprintf(m_termout,"%c%d,0%c",m_escchar,n,E_MAKEWIN)_m_flsh)

#define m_selectwin(n) \
	(fprintf(m_termout,"%c%d%c",m_escchar,n,E_MAKEWIN)_m_flsh)

/* events */

#define m_setevent(event,x) \
	(fprintf(m_termout,"%c%d,%d%c%s", \
	m_escchar,_mapevent(event),strlen(x),E_EVENT,x)_m_flsh)

#define m_clearevent(event) \
	(fprintf(m_termout,"%c%d%c", \
	m_escchar,_mapevent(event),E_EVENT)_m_flsh)

/* message passing */

#define m_sendme(str) \
	(fprintf(m_termout,"%c%d%c%s", \
	m_escchar,strlen(str),E_GIMME,str)_m_flsh)

#define m_sendto(pid,str) \
	(fprintf(m_termout,"%c%d,%d%c%s", \
	m_escchar,pid,strlen(str),E_SEND,str)_m_flsh)

#define m_broadcast(str) \
	(fprintf(m_termout,"%c%d%c%s", \
	m_escchar,strlen(str),E_SEND,str)_m_flsh)

#define m_snarf(str) \
	(fprintf(m_termout,"%c%d%c%s", \
	m_escchar,strlen(str),E_SNARF,str)_m_flsh)

#define m_put() \
	(fprintf(m_termout,"%c%c", \
	m_escchar,E_PUTSNARF)_m_flsh)

/* environment stacking */

#define m_push(mode) \
	(m_envcount++, \
         fprintf(m_termout,"%c%d%c",m_escchar,(mode)|P_CLEAR,E_PUSH) \
         _m_flsh)

#define m_pushsave(mode) \
	(m_envcount++, \
	fprintf(m_termout,"%c%d%c",m_escchar,(mode),E_PUSH)_m_flsh)

#define m_pop() \
	(m_envcount?m_envcount--:0, \
         fprintf(m_termout,"%c%c",m_escchar,E_POP)_m_flsh)

#define m_popall() \
	while(m_envcount--) \
         (fprintf(m_termout,"%c%c",m_escchar,E_POP)_m_flsh)

/* tty mode settings */

#ifdef SYSV
#define m_setraw() \
	m_resetflags(ICANON|ECHO)
#else
#define m_setraw() \
	m_setflags(RAW)
#endif

#ifdef SYSV
#define m_setnoraw() \
	m_setflags(ICANON|ECHO)
#else
#define m_setnoraw() \
	m_resetflags(RAW)
#endif

#define m_unsetraw	m_setnoraw		/* obsolete */

#define m_setecho()	 \
        m_setflags(ECHO)

#define m_setnoecho() \
        m_resetflags(ECHO)

/* other stuff */

#define m_setmode(mode) \
	(fprintf(m_termout,"%c%d%c",m_escchar,mode,E_SETMODE)_m_flsh)

#define m_dupkey(key) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,M_DUPKEY,key,E_SETMODE)_m_flsh)

#define m_clearmode(mode) \
	(fprintf(m_termout,"%c%d%c",m_escchar,mode,E_CLEARMODE)_m_flsh)

#define m_getinfo(x) \
	(fprintf(m_termout,"%c%d%c",m_escchar,x,E_GETINFO),m_flush())

#define m_whatsat(x,y) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,x,y,E_GETINFO),m_flush())

#define m_get()\
	(m_flush(),fgets(m_linebuf,sizeof(m_linebuf),m_termin))

#define m_getchar()\
	(getc(m_termin))

#define m_gets(buff)\
	(m_flush(),fgets(buff,sizeof(buff),m_termin))

#define m_putchar(c) \
	(putc(c,m_termout)_m_flsh)

#define m_printstr(str) \
	(fprintf(m_termout,"%s",str)_m_flsh)

#define m_setesc(x) \
	(m_escchar = (x))

#define m_resetesc() \
	(m_escchar = ESC)

#define m_sleep() \
	(fprintf(m_termout,"%c%c",m_escchar,E_NULL)_m_flsh)

/* menu stuff */

#ifndef M_DELIM
#define M_DELIM	'\005'		/* menu delimiter character */
#endif

#define m_selectmenu(n) \
	(fprintf(m_termout,"%c%d%c",m_escchar,n,E_MENU)_m_flsh)

#define m_selectmenu2(n) \
	(fprintf(m_termout,"%c-%d%c",m_escchar,n,E_MENU)_m_flsh)

#define m_nomenu() \
	(fprintf(m_termout,"%c%d%c",m_escchar,999,E_MENU)_m_flsh)

#define m_nomenu2() \
	(fprintf(m_termout,"%c-%d%c",m_escchar,999,E_MENU)_m_flsh)

#define m_loadmenu(n,str) \
	(fprintf(m_termout,"%c%d,%d%c%s",m_escchar,n,strlen(str),E_MENU,str)_m_flsh)

#define m_clearmenu(n) \
	(fprintf(m_termout,"%c%d,0%c",m_escchar,n,E_MENU)_m_flsh)

#define m_linkmenu(parent,item,child,flags) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c", \
	m_escchar,parent,item,child,flags,E_MENU)_m_flsh)

#define m_unlinkmenu(parent,item) \
	(fprintf(m_termout,"%c%d,%d,%d,%c", \
	m_escchar,parent,item,-1,E_MENU)_m_flsh)

#define m_pagemenu(parent,child) \
	(fprintf(m_termout,"%c%d,%d,%d,%c", \
	m_escchar,parent,-1,child,E_MENU)_m_flsh)

#define m_unpagemenu(parent) \
	(fprintf(m_termout,"%c%d,%d,%d,%c", \
	m_escchar,parent,-1,-1,E_MENU)_m_flsh)

/* temporary menu stuff */

#define m_menuitem(menu,item) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,menu,item,E_FOO)_m_flsh)

#define m_menuerase(menu) \
	(fprintf(m_termout,"%c%d%c",m_escchar,menu,E_FOO)_m_flsh)

#define m_menushow(x,y,menu) \
	(fprintf(m_termout,"%c%d,%d,%d%c",m_escchar,x,y,menu,E_FOO)_m_flsh)

#define m_menubar(x,y,menu,item) \
	(fprintf(m_termout,"%c%d,%d,%d,%d%c",m_escchar,x,y,menu,item,E_FOO)_m_flsh)

/* temporary relative character motion */

#define m_right(tenths) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,tenths,10,E_RIGHT)_m_flsh)

#define m_left(tenths) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,tenths,-10,E_RIGHT)_m_flsh)

#define m_up(tenths) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,tenths,10,E_UP)_m_flsh)

#define m_down(tenths) \
	(fprintf(m_termout,"%c%d,%d%c",m_escchar,tenths,10,E_DOWN)_m_flsh)

/* color stuff */

#define m_fcolor(color) \
        (fprintf(m_termout,"%c%d%c",m_escchar,color,E_FCOLOR)_m_flsh)
#define m_bcolor(color) \
        (fprintf(m_termout,"%c%d%c",m_escchar,color,E_BCOLOR)_m_flsh)
#define m_linecolor(op,color) \
        (fprintf(m_termout,"%c%d,%d%c",m_escchar,op,color,E_BITBLT)_m_flsh)

#define _mapevent(z)				((z)==3||(z)==4?2-(z):z)

/* events */

#define BUTTON_1		1		/* end button depressed */
#define BUTTON_2		2		/* middle button depressed */
#define BUTTON_1U		3		/* end button released */
#define BUTTON_2U		4		/* middle button released */
#define RESHAPE			5		/* window was reshaped */
#define RESHAPED		5		/* window was reshaped */
#define REDRAW			6		/* screen was redrawn */
#define REDRAWN			6		/* screen was redrawn */
#define ACTIVATE		7		/* window was activated */
#define ACTIVATED		7		/* window was activated */
#define DEACTIVATE		8		/* window was deactivated */
#define DEACTIVATED		8		/* window was deactivated */
#define COVERED			9		/* window was covered */
#define UNCOVERED		10		/* window was uncovered */
#define MOVE			11		/* window was moved */
#define MOVED			11		/* window was moved */
#define DESTROY			12		/* window was destroyed */
#define ACCEPT			13		/* accept messages */
#define NOTIFY			14		/* set notification */
#define SNARFED			16		/* text was just snarfed */
#define PASTE			17		/* text was just pasted */

/* stuff for setting terminal modes */

#define _m_ttyset()		(m_flags&M_MODEOK?m_flags:m_ttyset())
#define _m_ttyreset()		(m_flags&M_MODEOK?m_flags:m_ttyreset())

/* global variables */

#define MAXLINE		256	/* maximum line size from mgr */

extern FILE *m_termin;		/* output to window */
extern FILE *m_termout;		/* input from mgr */
extern int m_flags;		/* setup flags */
extern int m_envcount;		/* # of stacked environments */
extern int m_saveenvcount;	/* ??? */
extern char m_escchar;		/* \033, change only for debugging */
extern char m_menuchar;		/* menu field seperator char (\005) */
extern char m_linebuf[MAXLINE];

extern int get_info(), get_size(), parse(), get_font(), is_active(), menu_load();
extern char *m_lastline(), *get_termcap();

/* structure definitions */

#define MENU_SIZE(x)	(sizeof(x)/sizeof(struct menu_entry))

struct menu_entry {
   char *value;		/* this appears in the menu */
   char *action;	/* this gets sent by mgr upon selection */
   };

struct window_data {
   int x,y;		/* origin */
   int w,h;		/* width, height */
   char tty[3];		/* name of controlling tty */
   char status;		/* activation status */
   int num;		/* window number (>0 for client) */
   int setid;		/* window set ID */
   };

struct icon {
   char *name;		/* name of icon */
   int type;		/* always 1 */
   int w;		/* bitmap width */
   int h;		/* bitmap height */
   unsigned char *data;	/* data goes here */
   };

#endif _TERM_INCL
@//E*O*F term.h//
chmod u=rw,g=r,o=r term.h
 
echo x - window.h
sed 's/^@//' > "window.h" <<'@//E*O*F window.h//'
/*                        Copyright (c) 1988 Bellcore
 *                            All Rights Reserved
 *       Permission is granted to copy or use this program, EXCEPT that it
 *       may not be sold for profit, the copyright notice must be reproduced
 *       on copies, and credit should be given to Bellcore where it is due.
 *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
 */
/*	$Header: window.h,v 4.2 88/08/12 07:41:26 sau Exp $
	$Source: /tmp/mgrsrc/lib/RCS/window.h,v $
*/
static char	h_window_[] = "$Source: /tmp/mgrsrc/lib/RCS/window.h,v $$Revision: 4.2 $";

/* defines for terminal emulator */

/* text flags - for commands with text string arguments */

#define T_INVALID	0	/* invalid command */
#define T_FONT		1	/* down load a new font */
#define T_MENU		2	/* down load a menu */
#define T_EVENT		3	/* down load an event string */
#define T_YANK		4	/* fill the yank bufffer */
#define T_BITMAP	5	/* down load a bit map */
#define T_COMMAND	6	/* start a new window & command in it */
#define T_GIMME		7	/* send me stuff */
#define T_SMAP		8	/* save a bitmap on a file */
#define T_GMAP		9	/* read a bitmap from a file */
#define T_SEND		10	/* send a message to another application */
#define T_GRUNCH	11	/* fast-draw, short vector mode */
#define T_STRING	12	/* write a text sting into an offscreen bitmap */

/* option codes for GETMODE / SETMODE  */

#define M_STANDOUT	0	/* window is in standout mode  */
#define M_WOB		1	/* window is white on black  */
#define M_AUTOEXPOSE	2	/* expose window upon shell output  */
#define M_BACKGROUND	3	/* permit obscured window to update  */
#define M_NOINPUT	4	/* don't accept keyboard input  */
#define M_NOWRAP	5	/* don't auto wrap  */
#define M_OVERSTRIKE	6	/* overstrike mode  */
#define M_ABS		7	/* use absolute coordinates  */
#define M_ACTIVATE	8	/* activate / hide window; not a mode */
#define M_STACK		12	/* permit event stacking */
#define M_DUPKEY	13	/* set keyboard escape key */
#define M_NOBUCKEY	14	/* prevent mgr processing buckey keys,
				   pass them through to the application */

/* cut/paste options */

#define M_SNARFLINES	9	/* only snarf entire lines */
#define M_SNARFTABS	10	/* change spaces to tabs in snarf */
#define M_SNARFHARD	11	/* snarf even if errors */

/* option codes for GETINFO */

#define G_MOUSE	 	0	/* mouse coordinates  */
#define G_TERMCAP 	1	/* send back termcap entry  */
#define G_WINSIZE 	2	/* cols, lines  */
#define G_FONT	 	3	/* font wide, high, #  */
#define G_COORDS 	4	/* window coords  */
#define G_STATUS 	5	/* window status  */
#define G_ALL	 	6	/* complete window status  */
#define G_SYSTEM 	7	/* system status  */
#define G_ALLFONT 	8	/* font information  */
#define G_TEXT		9	/* text region size */
#define G_ALLMINE  	10	/* window status for client windows */
#define G_CURSOR	11	/* character/ graphics cursor position */
#define G_MOUSE2	12	/* cooked mouse coordinates  */
#define G_NOTIFY	13	/* gimme info re notify windows */
#define G_ID		14	/* my client window number */
#define G_FLAGS		15	/* current window flags */
#define G_MAX		15	/* maximum GETINFO value */

/* option codes for stacking window environment */

#define P_MENU		0x001	/* push menus */
#define P_EVENT		0x002	/* push events */
#define P_FONT		0x004	/* push current font */
#define P_CURSOR	0x008	/* push current cursor position  */
#define P_BITMAP	0x010	/* push saved bitmaps */
#define P_POSITION	0x020	/* push window location */
#define P_WINDOW	0x040	/* push window contents */
#define P_FLAGS		0x080	/* push window flags */
#define P_MOUSE		0x100	/* push mouse position */
#define P_TEXT		0x200	/* push text region */


#define P_ALL		0x3ff	/* push everything */
#define P_MAX		0x400	/* end of codes marker */
#define P_DEFAULT	(P_MENU | P_EVENT | P_FONT | P_FLAGS | P_TEXT)
#define P_CLEAR		0x400	/* clear new environment */

/* menu_flags */

#define MF_SNIP		8	/* don't send action for parent of s/o menu */
#define MF_PAGE		4	/* auto-page for menus */
#define MF_AUTO		2	/* auto-right exit for menus */
#define MF_CLEAR	1	/* clear menu flags */

/* Escape codes */

#define ESC		'\033'	/* escape character */

#define E_MINUS		'-'	/* set the munus flag */
#define E_SEP1		','	/* primary field seperator */
#define E_SEP2		';'	/* secondary field seperator */
#define E_MOUSE		'?'	/* testing  -- move the mouse  */
#define E_ADDLINE	'a'	/* add a new line  */
#define E_ADDCHAR	'A'	/* add a character  */
#define E_BITBLT	'b'	/* do a bit blit  */
#define E_BITCRT	'B'	/* create a bit blit  */
#define E_CLEAREOL	'c'	/* clear  */
#define E_CLEAREOS	'C'	/* clear  */
#define E_DELETELINE	'd'	/* delete a line */
#define E_BITLOAD	'D'	/* download a bitmap  */
#define E_EVENT		'e'	/* download events  */
#define E_DELETECHAR	'E'	/* delete a char */
#define E_DOWN		'f'	/* down 1 line */
#define E_FONT		'F'	/* pick a new font  */
#define E_GO		'g'	/* Go; move graphics pointer  */
#define E_MOVE		'G'	/* move to x,y pixels  */
#define E_SETCURSOR	'h'	/* select cursor style */
#define E_BLEEP		'H'	/* blink a section of the screen */
#define E_GETINFO	'I'	/* get info from mgr */
#define E_STANDOUT	'i'	/* start standout mode */
#define E_FCOLOR	'j'	/* set forground color */
#define E_BCOLOR	'J'	/* set background color */
#define E_LINE		'l'	/* Plot a line  */
#define E_LINK		'L'	/* menu links */
#define E_MENU		'm'	/* download menus */
#define E_CUP		'M'	/* move to col, row (zero origin)  */
#define E_STANDEND	'n'	/* end standout mode */
#define E_CIRCLE	'o'	/* Plot a circle or an ellipse or an arc */
#define E_PUSH		'P'	/* push window environment */
#define E_POP		'p'	/* pop window environment */
#define E_RUBBER	'R'	/* rubber band a line/rect (obsolete) */
#define E_RIGHT		'r'	/* right 1 column  */
#define E_CLEARMODE	's'	/* clear window mode */
#define E_SETMODE	'S'	/* set a window mode */
#define E_TEXTREGION	't'	/* set the text region */
#define E_UPLINE	'u'	/* up 1 line  */
#define E_BITGET	'U'	/* upload a bitmap  */
#define E_SHAPE		'W'	/* reshape window, make it active  */
#define E_SIZE		'w'	/* reshape window: cols,rows  */
#define E_GIMME		'x'	/* send me data */
#define E_PUTSNARF	'y'	/* put the snarf buffer  */
#define E_SNARF		'Y'	/* snarf text into the snarf buffer  */
#define E_VI		'V'	/* set vi mode */
#define E_NOVI		'v'	/* turn off vi mode */
#define E_HALFWIN	'z'	/* make a 1/2 window */
#define E_MAKEWIN	'Z'	/* make/goto a new window */
#define E_NULL		'$'	/* do nothing, force exit */
#define E_SMAP		'>'	/* save a bitmap */
#define E_GMAP		'<'	/* get a bitmap */
#define E_SEND		'|'	/* send a message to another application */
#define E_CURSOR	'%'	/* set mouse cursor */
#define E_GRUNCH	':'	/* graphics crunch mode (experimental) */
#define E_STRING	'.'	/* write characters in offscreen bitmap */
#ifdef XMENU
#define E_XMENU		'X'	/* extended menu operations */
#endif


/* misc */

#define C_NOCHAR	'?'	/* for character not in font */
#define C_EXPOSED	'e'	/* window is not obscured */
#define C_ACTIVE	'a'	/* window has input focus */
#define C_NOTACTIVE	'n'	/* window is obscured */
#define C_OBSCURED	'o'	/* window is obscured */
#define C_NAME		"px|mgr|mgr teminal emulator"

#define C_NULL		'\000'	/* null */
#define C_BS		'\b'	/* back space */
#define C_FF		'\f'	/* form feed */
#define C_BELL		'\007'	/* bell */
#define C_TAB		'\t'	/* tab */
#define C_RETURN	'\r'	/* return */
#define C_NL		'\n'	/* line feed */

/* cursor styles */
#define CS_BLOCK		0		/* standard block cursor */
#define CS_LEFT		1		/* left vertical bar */
#define CS_RIGHT		2		/* right vertical bar */
#define CS_BOX			3		/* outline */
#define CS_UNDER		4		/* underline */
#define CS_INVIS		9		/* invisible */

/* some raster op functions  (for bit_copy) */

#ifndef BIT_NOT
#define BIT_NOT(x)	(~(x))		/* from bitmap.h */
#endif
#define B_SRC		(0xc)
#define B_DST		(0xa)
#define B_OR		(B_SRC|B_DST)
#define B_COPY		(B_SRC)
#define B_COPYINVERTED	((BIT_NOT(B_SRC))&0xf)
#define B_XOR		(B_SRC^B_DST)
#define B_AND		(B_SRC&B_DST)

/* raster op functions  (for bit_write and bit_line) */

#define B_SET		(0xf)
#define B_CLEAR		(0x0)
#define B_INVERT	((BIT_NOT(B_DST))&0xf)

/* where to find icon directory */

#ifndef ICONDIR
#  define ICONDIR		"/usr/mgr/icon"	/* readable by all icons */
#endif

/* other macros */

#define Scalex(x) \
	(W(flags)&W_ABSCOORDS ?  (x) :  (x) * (int)BIT_WIDE(W(window))/GMAX)
#define Scaley(y) \
	(W(flags)&W_ABSCOORDS ?  (y) :  (y) * (int)BIT_HIGH(W(window))/GMAX)
#define Scalexy(y) \
	(W(flags)&W_ABSCOORDS ?  (y) : \
	 (y) * (int)(BIT_HIGH(W(window))+BIT_WIDE(W(window)))/(2*GMAX))

#define FSIZE(c)	((int) (W(font)->head.c))
#define WIDE	        BIT_WIDE(window)
#define HIGH	        BIT_HIGH(window)
#define T_WIDE	        BIT_WIDE(text)
#define T_HIGH	        BIT_HIGH(text)
@//E*O*F window.h//
chmod u=rw,g=r,o=r window.h
 
echo x - mgrload.1
sed 's/^@//' > "mgrload.1" <<'@//E*O*F mgrload.1//'
@.TH mgrload 1L "June 21, 1990"
@.SH NAME
mgrload -\ Graph of system load average
@.SH SYNOPSIS
@.B mgrload
[\fB\-x\fP<pos>]
[\fB\-y\fP<pos>]
[\fB\-l\fP<pixels>]
[\fB\-w\fP<pixels>]
@.SH DESCRIPTION
@.I Mgrload
uses the
@.I loadavgd
daemon to extract information from the kernel to determine the current cpu
load.  The load is represented as a floating point number
greater than or equal to zero and represents the average number of processes
which were on the run queue during the past 60 seconds.
@.I Mgrload 
represents this data as a scrolling bar graph with each bar
representing the load during a 60 second interval.  The vertical scale of
the graph is dynamically adjusted to account for changing load average
values.  Horizontal lines are placed on the graph spaced at a value
of 0.50 apart.  Precise values for the displayed maximum, minimum and most
recent load value can be shown using the menu available when the right
mouse button is pressed.  System information such as the host name is
available by pressing the middle mouse button.  This information can be
useful when
@.I mgrload
is run in a networked environment and several
@.I mgrloads
are running to display load averages of remote systems.
Additional funtions such as redrawing the graph and resetting all stored
values are also available by pressing the right mouse button.
@.LP
@.B mgrload
recognizes the following command line flags:
@.TP 
-x<pos>
Starting x-coordinate of graph
@.TP 
-y<pos>
Starting y-coordinate of graph
@.TP 
-l<pixels>
Length of graph in pixels
@.TP 
-w<pixels>
Width of graph in pixels
@.SH BUGS
If the shared memory segment which
@.I loadavgd
creates is removed,
@.I mgrload
will crash with a bus error.
@.LP
Killing
@.I loadavgd
is a bad thing to do.
@.SH AUTHOR
Mark Dapoz 
@.br
mdapoz%hybrid@cs.toronto.edu
@//E*O*F mgrload.1//
chmod u=rw,g=r,o=r mgrload.1
 
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
     11     85    565 README
     32    118    823 Makefile
    277   1043   7784 mgrload.c
    344   1306   8268 loadavgd.c
    567   1217  15542 term.h
    227   1465   8764 window.h
     62    289   1786 mgrload.1
   1520   5523  43532 total
!!!
wc  README Makefile mgrload.c loadavgd.c term.h window.h mgrload.1 | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0
-- 
Managing a software development team 	|   Mark Dapoz  
is a lot like being on the psychiatric	|   mdapoz%hybrid@cs.toronto.edu
ward.  -Mitch Kapor, San Jose Mercury	|   mdapoz@torvm3.iinus1.ibm.com



