884 lines · 14.8 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <draw.h>#include <event.h>#include <bio.h>#include <keyboard.h>#include "cons.h" enum{	Ehost		= 4,}; char	*menutext2[] = {	"backup",	"forward",	"reset",	"clear",	"send",	"page",	0}; char	*menutext3[] = {	"24x80",	"crnl",	"nl",	"raw",	"exit",	0}; /* variables associated with the screen */ int	x, y;	/* character positions */char	*backp;int	backc;int	atend;int	nbacklines;int	xmax, ymax;int	blocked;int	resize_flag;int	pagemode;int	olines;int	peekc;int	cursoron = 1;Menu	menu2;Menu	menu3;char	*histp;char	hist[HISTSIZ];int	yscrmin, yscrmax;int	attr, defattr;int	wctlout; Image	*bordercol;Image	*cursback;Image	*colors[8];Image	*hicolors[8];Image	*red;Image	*fgcolor;Image	*bgcolor;Image	*fgdefault;Image	*bgdefault; uint rgbacolors[8] = {	0x000000FF,	/* black */	0xAA0000FF,	/* red */	0x00AA00FF,	/* green */	0xFF5500FF,	/* brown */	0x0000FFFF,	/* blue */	0xAA00AAFF,	/* purple */	0x00AAAAFF,	/* cyan */	0x7F7F7FFF,	/* white */}; ulong rgbahicolors[8] = {	0x555555FF,	/* light black aka grey */	0xFF5555FF,	/* light red */	0x55FF55FF,	/* light green */	0xFFFF55FF,	/* light brown aka yellow */	0x5555FFFF,	/* light blue */	0xFF55FFFF,	/* light purple */	0x55FFFFFF,	/* light cyan */	0xFFFFFFFF,	/* light grey aka white */}; /* terminal control */struct ttystate ttystate[2] = { {0, 1}, {0, 1} }; int	NS;int	CW;Consstate *cs;Mouse	mouse; int	debug;int	nocolor;int	logfd = -1;int	outfd = -1;Biobuf	*snarffp = 0; char	*host_buf;char	*hostp;				/* input from host */int	host_bsize = 2*BSIZE;int	hostlength;			/* amount of input from host */char	echo_input[BSIZE];char	*echop = echo_input;		/* characters to echo, after canon */char	sendbuf[BSIZE];	/* hope you can't type ahead more than BSIZE chars */char	*sendp = sendbuf; char *term;struct funckey *fk; /* functions */void	initialize(int, char **);void	ebegin(int);int	waitchar(void);int	rcvchar(void);void	set_input(char *);void	set_host(Event *);void	bigscroll(void);void	readmenu(void);void	eresized(int);void	resize(void);void	send_interrupt(void);int	alnum(int);void	escapedump(int,uchar *,int); voidmain(int argc, char **argv){	initialize(argc, argv);	emulate();} voidusage(void){	fprint(2, "usage: %s [-2abcx] [-f font] [-l logfile]\n", argv0);	exits("usage");} voidinitialize(int argc, char **argv){	int i, blkbg;	char *fontname, *p; 	rfork(RFNAMEG|RFNOTEG); 	fontname = nil;	term = "vt100";	fk = vt100fk;	blkbg = nocolor = 0;	ARGBEGIN{	case '2':		term = "vt220";		fk = vt220fk;		break;	case 'a':		term = "ansi";		fk = ansifk;		break;	case 'b':		blkbg = 1;		/* e.g., for linux colored output */		break;	case 'c':		nocolor = 1;		break;	case 'f':		fontname = EARGF(usage());		break;	case 'l':		p = EARGF(usage());		logfd = create(p, OWRITE, 0666);		if(logfd < 0)			sysfatal("could not create log file: %s: %r", p);		break;	case 'x':		fk = xtermfk;		term = "xterm";		break;	default:		usage();		break;	}ARGEND; 	host_buf = malloc(host_bsize);	hostp = host_buf;	hostlength = 0; 	if(initdraw(0, fontname, term) < 0){		fprint(2, "%s: initdraw failed: %r\n", term);		exits("initdraw");	}	werrstr("");		/* clear spurious error messages */	ebegin(Ehost); 	histp = hist;	menu2.item = menutext2;	menu3.item = menutext3;	pagemode = 0;	blocked = 0;	NS = font->height;	CW = stringwidth(font, "m"); 	red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);	bordercol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCCC);	cursback = allocimage(display, Rect(0, 0, CW+1, NS+1), screen->chan, 0, DNofill); 	for(i=0; i<8; i++){		colors[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1,			rgbacolors[i]);		hicolors[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1,			rgbahicolors[i]);	} 	bgdefault = (blkbg? display->black: display->white);	fgdefault = (blkbg? display->white: display->black);	bgcolor = bgdefault;	fgcolor = fgdefault; 	resize(); 	if(argc > 0) {		sendnchars(strlen(argv[0]),argv[0]);		sendnchars(1,"\n");	}} voidclear(Rectangle r){	draw(screen, r, bgcolor, nil, ZP);} voidnewline(void){	nbacklines--;	if(y >= yscrmax) {		y = yscrmax;		if(pagemode && olines >= yscrmax) {			blocked = 1;			return;		}		scroll(yscrmin+1, yscrmax+1, yscrmin, yscrmax);	} else		y++;	olines++;} voidcursoff(void){	draw(screen, Rpt(pt(x, y), addpt(pt(x, y), Pt(CW,NS))), 		cursback, nil, cursback->r.min);} voidcurson(int bl){	Image *col; 	if(!cursoron){		cursoff();		return;	} 	draw(cursback, cursback->r, screen, nil, pt(x, y));	if(bl)		col = red;	else		col = bordercol;	border(screen, Rpt(pt(x, y), addpt(pt(x, y), Pt(CW,NS))), 2, col, ZP);} intget_next_char(void){	int c = peekc;	uchar buf[1];	peekc = 0;	if(c > 0)		return(c);	while(c <= 0) {		if(backp) {			c = *backp;			if(c && nbacklines >= 0) {				backp++;				if(backp >= &hist[HISTSIZ])					backp = hist;				return(c);			}			backp = 0;		}		c = (uchar)waitchar();		if(c > 0 && logfd >= 0) {			buf[0] = c;			write(logfd, buf, 1);		}	}	*histp++ = c;	if(histp >= &hist[HISTSIZ])		histp = hist;	*histp = '\0';	return(c);} intcanon(char *ep, int c){	if(c&0200)		return(SCROLL);	switch(c) {		case '\b':			if(sendp > sendbuf)				sendp--;			*ep++ = '\b';			*ep++ = ' ';			*ep++ = '\b';			break;		case 0x15:	/* ^U line kill */			sendp = sendbuf;			*ep++ = '^';			*ep++ = 'U';			*ep++ = '\n';			break;		case 0x17:	/* ^W word kill */			while(sendp > sendbuf && !alnum(*sendp)) {				*ep++ = '\b';				*ep++ = ' ';				*ep++ = '\b';				sendp--;			}			while(sendp > sendbuf && alnum(*sendp)) {				*ep++ = '\b';				*ep++ = ' ';				*ep++ = '\b';				sendp--;			}			break;		case '\177':	/* interrupt */			sendp = sendbuf;			send_interrupt();			return(NEWLINE);		case '\021':	/* quit */		case '\r':		case '\n':			if(sendp < &sendbuf[512])				*sendp++ = '\n';			sendnchars((int)(sendp-sendbuf), sendbuf);			sendp = sendbuf;			if(c == '\n' || c == '\r') {				*ep++ = '\n';			}			*ep = 0;			return(NEWLINE);		case '\004':	/* EOT */			if(sendp == sendbuf) {				sendnchars(0,sendbuf);				*ep = 0;				return(NEWLINE);			}			/* fall through */		default:			if(sendp < &sendbuf[512])				*sendp++ = c;			*ep++ = c;			break;			}	*ep = 0;	return(OTHER);} voidsendfk(char *name){	int i;	static int fd; 	for(i=0; fk[i].name; i++)		if(strcmp(name, fk[i].name)==0){			sendnchars2(strlen(fk[i].sequence), fk[i].sequence);			return;		}} intwaitchar(void){	Event e;	int c;	char c2;	int newmouse;	int wasblocked;	int kbdchar = -1;	char echobuf[3*BSIZE];	static int lastc = -1;  	for(;;) {		if(resize_flag)			resize();		wasblocked = blocked;		if(backp)			return(0);		if(ecanmouse() && (button2() || button3()))			readmenu();		if(snarffp) {			if((c = Bgetc(snarffp)) < 0) {				if(lastc != '\n')					write(outfd,"\n",1);				Bterm(snarffp);				snarffp = 0;				if(lastc != '\n') {					lastc = -1;					return('\n');				}				lastc = -1;				continue;			}			lastc = c;			c2 = c;			write(outfd, &c2, 1);			return(c);		}		if(!blocked && host_avail())			return(rcvchar());		if(kbdchar > 0) {			if(blocked)				resize();			if(cs->raw) {				switch(kbdchar){				case Kup:					sendfk("up key");					break;				case Kdown:					sendfk("down key");					break;				case Kleft:					sendfk("left key");					break;				case Kright:					sendfk("right key");					break;				case Kpgup:					sendfk("page up");					break;				case Kpgdown:					sendfk("page down");					break;				case KF|1:					sendfk("F1");					break;				case KF|2:					sendfk("F2");					break;				case KF|3:					sendfk("F3");					break;				case KF|4:					sendfk("F4");					break;				case KF|5:					sendfk("F5");					break;				case KF|6:					sendfk("F6");					break;				case KF|7:					sendfk("F7");					break;				case KF|8:					sendfk("F8");					break;				case KF|9:					sendfk("F9");					break;				case KF|10:					sendfk("F10");					break;				case KF|11:					sendfk("F11");					break;				case KF|12:					sendfk("F12");					break;				case '\n':					echobuf[0] = '\r';					sendnchars(1, echobuf);					break;

Lines 1–500 of 884.