xref: /plan9/sys/src/cmd/vt/main.c (revision 21abd8f25aed5cdf552ef4ed86cf7cccb8b56d7c)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <event.h>
57dd7cddfSDavid du Colombier #include <bio.h>
67dd7cddfSDavid du Colombier #include <keyboard.h>
77dd7cddfSDavid du Colombier #include "cons.h"
87dd7cddfSDavid du Colombier 
97dd7cddfSDavid du Colombier enum{
107dd7cddfSDavid du Colombier 	Ehost		= 4,
117dd7cddfSDavid du Colombier };
127dd7cddfSDavid du Colombier 
137dd7cddfSDavid du Colombier char	*menutext2[] = {
147dd7cddfSDavid du Colombier 	"backup",
157dd7cddfSDavid du Colombier 	"forward",
167dd7cddfSDavid du Colombier 	"reset",
177dd7cddfSDavid du Colombier 	"clear",
187dd7cddfSDavid du Colombier 	"send",
197dd7cddfSDavid du Colombier 	"page",
207dd7cddfSDavid du Colombier 	0
217dd7cddfSDavid du Colombier };
227dd7cddfSDavid du Colombier 
237dd7cddfSDavid du Colombier char	*menutext3[] = {
247dd7cddfSDavid du Colombier 	"24x80",
257dd7cddfSDavid du Colombier 	"crnl",
267dd7cddfSDavid du Colombier 	"nl",
277dd7cddfSDavid du Colombier 	"raw",
2880ee5cbfSDavid du Colombier 	"exit",
297dd7cddfSDavid du Colombier 	0
307dd7cddfSDavid du Colombier };
317dd7cddfSDavid du Colombier 
327dd7cddfSDavid du Colombier /* variables associated with the screen */
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier int	x, y;	/* character positions */
357dd7cddfSDavid du Colombier char	*backp;
367dd7cddfSDavid du Colombier int	backc;
377dd7cddfSDavid du Colombier int	atend;
387dd7cddfSDavid du Colombier int	nbacklines;
397dd7cddfSDavid du Colombier int	xmax, ymax;
407dd7cddfSDavid du Colombier int	blocked;
417dd7cddfSDavid du Colombier int	resize_flag;
427dd7cddfSDavid du Colombier int	pagemode;
437dd7cddfSDavid du Colombier int	olines;
447dd7cddfSDavid du Colombier int	peekc;
4580ee5cbfSDavid du Colombier int	cursoron = 1;
467dd7cddfSDavid du Colombier Menu	menu2;
477dd7cddfSDavid du Colombier Menu	menu3;
487dd7cddfSDavid du Colombier char	*histp;
497dd7cddfSDavid du Colombier char	hist[HISTSIZ];
507dd7cddfSDavid du Colombier int	yscrmin, yscrmax;
517fb4e6f1SDavid du Colombier int	attr, defattr;
5232e56137SDavid du Colombier int	wctlout;
537dd7cddfSDavid du Colombier 
547dd7cddfSDavid du Colombier Image	*bordercol;
557dd7cddfSDavid du Colombier Image	*cursback;
567fb4e6f1SDavid du Colombier Image	*colors[8];
577fb4e6f1SDavid du Colombier Image	*hicolors[8];
587dd7cddfSDavid du Colombier Image	*red;
597fb4e6f1SDavid du Colombier Image	*fgcolor;
607fb4e6f1SDavid du Colombier Image	*bgcolor;
617fb4e6f1SDavid du Colombier Image	*fgdefault;
627fb4e6f1SDavid du Colombier Image	*bgdefault;
637fb4e6f1SDavid du Colombier 
647fb4e6f1SDavid du Colombier uint rgbacolors[8] = {
657fb4e6f1SDavid du Colombier 	0x000000FF,	/* black */
667fb4e6f1SDavid du Colombier 	0xAA0000FF,	/* red */
677fb4e6f1SDavid du Colombier 	0x00AA00FF,	/* green */
687fb4e6f1SDavid du Colombier 	0xFF5500FF,	/* brown */
697fb4e6f1SDavid du Colombier 	0x0000FFFF,	/* blue */
707fb4e6f1SDavid du Colombier 	0xAA00AAFF,	/* purple */
717fb4e6f1SDavid du Colombier 	0x00AAAAFF,	/* cyan */
727fb4e6f1SDavid du Colombier 	0x7F7F7FFF,	/* white */
737fb4e6f1SDavid du Colombier };
747fb4e6f1SDavid du Colombier 
757fb4e6f1SDavid du Colombier ulong rgbahicolors[8] = {
767fb4e6f1SDavid du Colombier 	0x555555FF,	/* light black aka grey */
777fb4e6f1SDavid du Colombier 	0xFF5555FF,	/* light red */
787fb4e6f1SDavid du Colombier 	0x55FF55FF,	/* light green */
797fb4e6f1SDavid du Colombier 	0xFFFF55FF,	/* light brown aka yellow */
807fb4e6f1SDavid du Colombier 	0x5555FFFF,	/* light blue */
817fb4e6f1SDavid du Colombier 	0xFF55FFFF,	/* light purple */
827fb4e6f1SDavid du Colombier 	0x55FFFFFF,	/* light cyan */
837fb4e6f1SDavid du Colombier 	0xFFFFFFFF,	/* light grey aka white */
847fb4e6f1SDavid du Colombier };
857dd7cddfSDavid du Colombier 
867dd7cddfSDavid du Colombier /* terminal control */
8780ee5cbfSDavid du Colombier struct ttystate ttystate[2] = { {0, 1}, {0, 1} };
887dd7cddfSDavid du Colombier 
897dd7cddfSDavid du Colombier int	NS;
907dd7cddfSDavid du Colombier int	CW;
917dd7cddfSDavid du Colombier Consstate *cs;
927dd7cddfSDavid du Colombier Mouse	mouse;
937dd7cddfSDavid du Colombier 
94*21abd8f2SDavid du Colombier int	debug;
95*21abd8f2SDavid du Colombier int	nocolor;
96*21abd8f2SDavid du Colombier int	logfd = -1;
977dd7cddfSDavid du Colombier int	outfd = -1;
987dd7cddfSDavid du Colombier Biobuf	*snarffp = 0;
997dd7cddfSDavid du Colombier 
1007dd7cddfSDavid du Colombier char	*host_buf;
1017dd7cddfSDavid du Colombier char	*hostp;				/* input from host */
1027dd7cddfSDavid du Colombier int	host_bsize = 2*BSIZE;
1037dd7cddfSDavid du Colombier int	hostlength;			/* amount of input from host */
1047dd7cddfSDavid du Colombier char	echo_input[BSIZE];
1057dd7cddfSDavid du Colombier char	*echop = echo_input;		/* characters to echo, after canon */
1067dd7cddfSDavid du Colombier char	sendbuf[BSIZE];	/* hope you can't type ahead more than BSIZE chars */
1077dd7cddfSDavid du Colombier char	*sendp = sendbuf;
1087dd7cddfSDavid du Colombier 
109*21abd8f2SDavid du Colombier char *term;
110*21abd8f2SDavid du Colombier struct funckey *fk;
111*21abd8f2SDavid du Colombier 
1127dd7cddfSDavid du Colombier /* functions */
1137dd7cddfSDavid du Colombier void	initialize(int, char **);
1147dd7cddfSDavid du Colombier void	ebegin(int);
1157dd7cddfSDavid du Colombier int	waitchar(void);
1167dd7cddfSDavid du Colombier int	rcvchar(void);
1177dd7cddfSDavid du Colombier void	set_input(char *);
1187dd7cddfSDavid du Colombier void	set_host(Event *);
1197dd7cddfSDavid du Colombier void	bigscroll(void);
1207dd7cddfSDavid du Colombier void	readmenu(void);
1217dd7cddfSDavid du Colombier void	eresized(int);
1227dd7cddfSDavid du Colombier void	resize(void);
1237dd7cddfSDavid du Colombier void	send_interrupt(void);
1247dd7cddfSDavid du Colombier int	alnum(int);
1257dd7cddfSDavid du Colombier void	escapedump(int,uchar *,int);
1267dd7cddfSDavid du Colombier 
1277dd7cddfSDavid du Colombier void
main(int argc,char ** argv)1287dd7cddfSDavid du Colombier main(int argc, char **argv)
1297dd7cddfSDavid du Colombier {
1307dd7cddfSDavid du Colombier 	initialize(argc, argv);
1317dd7cddfSDavid du Colombier 	emulate();
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier 
1347dd7cddfSDavid du Colombier void
usage(void)1357fb4e6f1SDavid du Colombier usage(void)
13680ee5cbfSDavid du Colombier {
137*21abd8f2SDavid du Colombier 	fprint(2, "usage: %s [-2abcx] [-f font] [-l logfile]\n", argv0);
13880ee5cbfSDavid du Colombier 	exits("usage");
13980ee5cbfSDavid du Colombier }
14080ee5cbfSDavid du Colombier 
14180ee5cbfSDavid du Colombier void
initialize(int argc,char ** argv)1427dd7cddfSDavid du Colombier initialize(int argc, char **argv)
1437dd7cddfSDavid du Colombier {
144*21abd8f2SDavid du Colombier 	int i, blkbg;
1457fb4e6f1SDavid du Colombier 	char *fontname, *p;
14659cc4ca5SDavid du Colombier 
1477fb4e6f1SDavid du Colombier 	rfork(RFNAMEG|RFNOTEG);
1487dd7cddfSDavid du Colombier 
1497fb4e6f1SDavid du Colombier 	fontname = nil;
1507dd7cddfSDavid du Colombier 	term = "vt100";
1517dd7cddfSDavid du Colombier 	fk = vt100fk;
152*21abd8f2SDavid du Colombier 	blkbg = nocolor = 0;
1537dd7cddfSDavid du Colombier 	ARGBEGIN{
154*21abd8f2SDavid du Colombier 	case '2':
155*21abd8f2SDavid du Colombier 		term = "vt220";
156*21abd8f2SDavid du Colombier 		fk = vt220fk;
15732e56137SDavid du Colombier 		break;
15880ee5cbfSDavid du Colombier 	case 'a':
15980ee5cbfSDavid du Colombier 		term = "ansi";
16080ee5cbfSDavid du Colombier 		fk = ansifk;
16180ee5cbfSDavid du Colombier 		break;
162*21abd8f2SDavid du Colombier 	case 'b':
163*21abd8f2SDavid du Colombier 		blkbg = 1;		/* e.g., for linux colored output */
1647dd7cddfSDavid du Colombier 		break;
165*21abd8f2SDavid du Colombier 	case 'c':
166*21abd8f2SDavid du Colombier 		nocolor = 1;
167*21abd8f2SDavid du Colombier 		break;
168*21abd8f2SDavid du Colombier 	case 'f':
169*21abd8f2SDavid du Colombier 		fontname = EARGF(usage());
17032e56137SDavid du Colombier 		break;
17180ee5cbfSDavid du Colombier 	case 'l':
1727fb4e6f1SDavid du Colombier 		p = EARGF(usage());
17380ee5cbfSDavid du Colombier 		logfd = create(p, OWRITE, 0666);
17480ee5cbfSDavid du Colombier 		if(logfd < 0)
17580ee5cbfSDavid du Colombier 			sysfatal("could not create log file: %s: %r", p);
17680ee5cbfSDavid du Colombier 		break;
177*21abd8f2SDavid du Colombier 	case 'x':
178*21abd8f2SDavid du Colombier 		fk = xtermfk;
179*21abd8f2SDavid du Colombier 		term = "xterm";
180*21abd8f2SDavid du Colombier 		break;
181*21abd8f2SDavid du Colombier 	default:
182*21abd8f2SDavid du Colombier 		usage();
183*21abd8f2SDavid du Colombier 		break;
1847dd7cddfSDavid du Colombier 	}ARGEND;
1857dd7cddfSDavid du Colombier 
1867dd7cddfSDavid du Colombier 	host_buf = malloc(host_bsize);
1877dd7cddfSDavid du Colombier 	hostp = host_buf;
1887dd7cddfSDavid du Colombier 	hostlength = 0;
1897dd7cddfSDavid du Colombier 
1907fb4e6f1SDavid du Colombier 	if(initdraw(0, fontname, term) < 0){
1917dd7cddfSDavid du Colombier 		fprint(2, "%s: initdraw failed: %r\n", term);
1927dd7cddfSDavid du Colombier 		exits("initdraw");
1937dd7cddfSDavid du Colombier 	}
194*21abd8f2SDavid du Colombier 	werrstr("");		/* clear spurious error messages */
1957dd7cddfSDavid du Colombier 	ebegin(Ehost);
1967dd7cddfSDavid du Colombier 
1977dd7cddfSDavid du Colombier 	histp = hist;
1987dd7cddfSDavid du Colombier 	menu2.item = menutext2;
1997dd7cddfSDavid du Colombier 	menu3.item = menutext3;
2007dd7cddfSDavid du Colombier 	pagemode = 0;
2017dd7cddfSDavid du Colombier 	blocked = 0;
2027fb4e6f1SDavid du Colombier 	NS = font->height;
2037fb4e6f1SDavid du Colombier 	CW = stringwidth(font, "m");
20432e56137SDavid du Colombier 
2057fb4e6f1SDavid du Colombier 	red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
2067dd7cddfSDavid du Colombier 	bordercol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCCC);
2077dd7cddfSDavid du Colombier 	cursback = allocimage(display, Rect(0, 0, CW+1, NS+1), screen->chan, 0, DNofill);
20880ee5cbfSDavid du Colombier 
2097fb4e6f1SDavid du Colombier 	for(i=0; i<8; i++){
210*21abd8f2SDavid du Colombier 		colors[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1,
211*21abd8f2SDavid du Colombier 			rgbacolors[i]);
212*21abd8f2SDavid du Colombier 		hicolors[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1,
213*21abd8f2SDavid du Colombier 			rgbahicolors[i]);
21480ee5cbfSDavid du Colombier 	}
2157dd7cddfSDavid du Colombier 
216*21abd8f2SDavid du Colombier 	bgdefault = (blkbg? display->black: display->white);
217*21abd8f2SDavid du Colombier 	fgdefault = (blkbg? display->white: display->black);
2187fb4e6f1SDavid du Colombier 	bgcolor = bgdefault;
2197fb4e6f1SDavid du Colombier 	fgcolor = fgdefault;
2207fb4e6f1SDavid du Colombier 
2217fb4e6f1SDavid du Colombier 	resize();
2227dd7cddfSDavid du Colombier 
2237dd7cddfSDavid du Colombier 	if(argc > 0) {
2247dd7cddfSDavid du Colombier 		sendnchars(strlen(argv[0]),argv[0]);
2257dd7cddfSDavid du Colombier 		sendnchars(1,"\n");
2267dd7cddfSDavid du Colombier 	}
2277dd7cddfSDavid du Colombier }
2287dd7cddfSDavid du Colombier 
2297dd7cddfSDavid du Colombier void
clear(Rectangle r)2307dd7cddfSDavid du Colombier clear(Rectangle r)
2317dd7cddfSDavid du Colombier {
2327fb4e6f1SDavid du Colombier 	draw(screen, r, bgcolor, nil, ZP);
2337dd7cddfSDavid du Colombier }
2347dd7cddfSDavid du Colombier 
2357dd7cddfSDavid du Colombier void
newline(void)2367dd7cddfSDavid du Colombier newline(void)
2377dd7cddfSDavid du Colombier {
2387dd7cddfSDavid du Colombier 	nbacklines--;
23980ee5cbfSDavid du Colombier 	if(y >= yscrmax) {
24080ee5cbfSDavid du Colombier 		y = yscrmax;
24180ee5cbfSDavid du Colombier 		if(pagemode && olines >= yscrmax) {
2427dd7cddfSDavid du Colombier 			blocked = 1;
2437dd7cddfSDavid du Colombier 			return;
2447dd7cddfSDavid du Colombier 		}
24580ee5cbfSDavid du Colombier 		scroll(yscrmin+1, yscrmax+1, yscrmin, yscrmax);
2467dd7cddfSDavid du Colombier 	} else
2477dd7cddfSDavid du Colombier 		y++;
2487dd7cddfSDavid du Colombier 	olines++;
2497dd7cddfSDavid du Colombier }
2507dd7cddfSDavid du Colombier 
2517dd7cddfSDavid du Colombier void
cursoff(void)25280ee5cbfSDavid du Colombier cursoff(void)
25380ee5cbfSDavid du Colombier {
2547fb4e6f1SDavid du Colombier 	draw(screen, Rpt(pt(x, y), addpt(pt(x, y), Pt(CW,NS))),
2557fb4e6f1SDavid du Colombier 		cursback, nil, cursback->r.min);
25680ee5cbfSDavid du Colombier }
25780ee5cbfSDavid du Colombier 
25880ee5cbfSDavid du Colombier void
curson(int bl)2597dd7cddfSDavid du Colombier curson(int bl)
2607dd7cddfSDavid du Colombier {
2617dd7cddfSDavid du Colombier 	Image *col;
2627dd7cddfSDavid du Colombier 
2637fb4e6f1SDavid du Colombier 	if(!cursoron){
2647fb4e6f1SDavid du Colombier 		cursoff();
26532e56137SDavid du Colombier 		return;
2667fb4e6f1SDavid du Colombier 	}
26732e56137SDavid du Colombier 
2687fb4e6f1SDavid du Colombier 	draw(cursback, cursback->r, screen, nil, pt(x, y));
2697dd7cddfSDavid du Colombier 	if(bl)
2707dd7cddfSDavid du Colombier 		col = red;
2717dd7cddfSDavid du Colombier 	else
2727dd7cddfSDavid du Colombier 		col = bordercol;
2739a747e4fSDavid du Colombier 	border(screen, Rpt(pt(x, y), addpt(pt(x, y), Pt(CW,NS))), 2, col, ZP);
2747dd7cddfSDavid du Colombier }
2757dd7cddfSDavid du Colombier 
2767dd7cddfSDavid du Colombier int
get_next_char(void)2777dd7cddfSDavid du Colombier get_next_char(void)
2787dd7cddfSDavid du Colombier {
2797dd7cddfSDavid du Colombier 	int c = peekc;
28080ee5cbfSDavid du Colombier 	uchar buf[1];
2817dd7cddfSDavid du Colombier 	peekc = 0;
2827dd7cddfSDavid du Colombier 	if(c > 0)
2837dd7cddfSDavid du Colombier 		return(c);
2847dd7cddfSDavid du Colombier 	while(c <= 0) {
2857dd7cddfSDavid du Colombier 		if(backp) {
2867dd7cddfSDavid du Colombier 			c = *backp;
2877dd7cddfSDavid du Colombier 			if(c && nbacklines >= 0) {
2887dd7cddfSDavid du Colombier 				backp++;
2897dd7cddfSDavid du Colombier 				if(backp >= &hist[HISTSIZ])
2907dd7cddfSDavid du Colombier 					backp = hist;
2917dd7cddfSDavid du Colombier 				return(c);
2927dd7cddfSDavid du Colombier 			}
2937dd7cddfSDavid du Colombier 			backp = 0;
2947dd7cddfSDavid du Colombier 		}
29580ee5cbfSDavid du Colombier 		c = (uchar)waitchar();
29680ee5cbfSDavid du Colombier 		if(c > 0 && logfd >= 0) {
29780ee5cbfSDavid du Colombier 			buf[0] = c;
29880ee5cbfSDavid du Colombier 			write(logfd, buf, 1);
29980ee5cbfSDavid du Colombier 		}
3007dd7cddfSDavid du Colombier 	}
3017dd7cddfSDavid du Colombier 	*histp++ = c;
3027dd7cddfSDavid du Colombier 	if(histp >= &hist[HISTSIZ])
3037dd7cddfSDavid du Colombier 		histp = hist;
3047dd7cddfSDavid du Colombier 	*histp = '\0';
3057dd7cddfSDavid du Colombier 	return(c);
3067dd7cddfSDavid du Colombier }
3077dd7cddfSDavid du Colombier 
3087dd7cddfSDavid du Colombier int
canon(char * ep,int c)3097dd7cddfSDavid du Colombier canon(char *ep, int c)
3107dd7cddfSDavid du Colombier {
3117dd7cddfSDavid du Colombier 	if(c&0200)
3127dd7cddfSDavid du Colombier 		return(SCROLL);
3137dd7cddfSDavid du Colombier 	switch(c) {
3147dd7cddfSDavid du Colombier 		case '\b':
3157dd7cddfSDavid du Colombier 			if(sendp > sendbuf)
3167dd7cddfSDavid du Colombier 				sendp--;
3177dd7cddfSDavid du Colombier 			*ep++ = '\b';
3187dd7cddfSDavid du Colombier 			*ep++ = ' ';
3197dd7cddfSDavid du Colombier 			*ep++ = '\b';
3207dd7cddfSDavid du Colombier 			break;
3217dd7cddfSDavid du Colombier 		case 0x15:	/* ^U line kill */
3227dd7cddfSDavid du Colombier 			sendp = sendbuf;
3237dd7cddfSDavid du Colombier 			*ep++ = '^';
3247dd7cddfSDavid du Colombier 			*ep++ = 'U';
3257dd7cddfSDavid du Colombier 			*ep++ = '\n';
3267dd7cddfSDavid du Colombier 			break;
3277dd7cddfSDavid du Colombier 		case 0x17:	/* ^W word kill */
3287dd7cddfSDavid du Colombier 			while(sendp > sendbuf && !alnum(*sendp)) {
3297dd7cddfSDavid du Colombier 				*ep++ = '\b';
3307dd7cddfSDavid du Colombier 				*ep++ = ' ';
3317dd7cddfSDavid du Colombier 				*ep++ = '\b';
3327dd7cddfSDavid du Colombier 				sendp--;
3337dd7cddfSDavid du Colombier 			}
3347dd7cddfSDavid du Colombier 			while(sendp > sendbuf && alnum(*sendp)) {
3357dd7cddfSDavid du Colombier 				*ep++ = '\b';
3367dd7cddfSDavid du Colombier 				*ep++ = ' ';
3377dd7cddfSDavid du Colombier 				*ep++ = '\b';
3387dd7cddfSDavid du Colombier 				sendp--;
3397dd7cddfSDavid du Colombier 			}
3407dd7cddfSDavid du Colombier 			break;
3417dd7cddfSDavid du Colombier 		case '\177':	/* interrupt */
3427dd7cddfSDavid du Colombier 			sendp = sendbuf;
3437dd7cddfSDavid du Colombier 			send_interrupt();
3447dd7cddfSDavid du Colombier 			return(NEWLINE);
3457dd7cddfSDavid du Colombier 		case '\021':	/* quit */
3467dd7cddfSDavid du Colombier 		case '\r':
3477dd7cddfSDavid du Colombier 		case '\n':
3487dd7cddfSDavid du Colombier 			if(sendp < &sendbuf[512])
3497dd7cddfSDavid du Colombier 				*sendp++ = '\n';
3507dd7cddfSDavid du Colombier 			sendnchars((int)(sendp-sendbuf), sendbuf);
3517dd7cddfSDavid du Colombier 			sendp = sendbuf;
3527dd7cddfSDavid du Colombier 			if(c == '\n' || c == '\r') {
3537dd7cddfSDavid du Colombier 				*ep++ = '\n';
3547dd7cddfSDavid du Colombier 			}
3557dd7cddfSDavid du Colombier 			*ep = 0;
3567dd7cddfSDavid du Colombier 			return(NEWLINE);
3577dd7cddfSDavid du Colombier 		case '\004':	/* EOT */
3587dd7cddfSDavid du Colombier 			if(sendp == sendbuf) {
3597dd7cddfSDavid du Colombier 				sendnchars(0,sendbuf);
3607dd7cddfSDavid du Colombier 				*ep = 0;
3617dd7cddfSDavid du Colombier 				return(NEWLINE);
3627dd7cddfSDavid du Colombier 			}
3637dd7cddfSDavid du Colombier 			/* fall through */
3647dd7cddfSDavid du Colombier 		default:
3657dd7cddfSDavid du Colombier 			if(sendp < &sendbuf[512])
3667dd7cddfSDavid du Colombier 				*sendp++ = c;
3677dd7cddfSDavid du Colombier 			*ep++ = c;
3687dd7cddfSDavid du Colombier 			break;
3697dd7cddfSDavid du Colombier 
3707dd7cddfSDavid du Colombier 	}
3717dd7cddfSDavid du Colombier 	*ep = 0;
3727dd7cddfSDavid du Colombier 	return(OTHER);
3737dd7cddfSDavid du Colombier }
3747dd7cddfSDavid du Colombier 
3757dd7cddfSDavid du Colombier void
sendfk(char * name)3767dd7cddfSDavid du Colombier sendfk(char *name)
3777dd7cddfSDavid du Colombier {
3787dd7cddfSDavid du Colombier 	int i;
3797dd7cddfSDavid du Colombier 	static int fd;
3807dd7cddfSDavid du Colombier 
3817dd7cddfSDavid du Colombier 	for(i=0; fk[i].name; i++)
3827dd7cddfSDavid du Colombier 		if(strcmp(name, fk[i].name)==0){
3837dd7cddfSDavid du Colombier 			sendnchars2(strlen(fk[i].sequence), fk[i].sequence);
3847dd7cddfSDavid du Colombier 			return;
3857dd7cddfSDavid du Colombier 		}
3867dd7cddfSDavid du Colombier }
3877dd7cddfSDavid du Colombier 
3887dd7cddfSDavid du Colombier int
waitchar(void)3897dd7cddfSDavid du Colombier waitchar(void)
3907dd7cddfSDavid du Colombier {
3917dd7cddfSDavid du Colombier 	Event e;
3927dd7cddfSDavid du Colombier 	int c;
3937dd7cddfSDavid du Colombier 	char c2;
3947dd7cddfSDavid du Colombier 	int newmouse;
3957dd7cddfSDavid du Colombier 	int wasblocked;
3967dd7cddfSDavid du Colombier 	int kbdchar = -1;
3977dd7cddfSDavid du Colombier 	char echobuf[3*BSIZE];
3987dd7cddfSDavid du Colombier 	static int lastc = -1;
3997dd7cddfSDavid du Colombier 
4007dd7cddfSDavid du Colombier 
4017dd7cddfSDavid du Colombier 	for(;;) {
4027dd7cddfSDavid du Colombier 		if(resize_flag)
4037dd7cddfSDavid du Colombier 			resize();
4047dd7cddfSDavid du Colombier 		wasblocked = blocked;
4057dd7cddfSDavid du Colombier 		if(backp)
4067dd7cddfSDavid du Colombier 			return(0);
4077dd7cddfSDavid du Colombier 		if(ecanmouse() && (button2() || button3()))
4087dd7cddfSDavid du Colombier 			readmenu();
4097dd7cddfSDavid du Colombier 		if(snarffp) {
4107dd7cddfSDavid du Colombier 			if((c = Bgetc(snarffp)) < 0) {
4117dd7cddfSDavid du Colombier 				if(lastc != '\n')
4127dd7cddfSDavid du Colombier 					write(outfd,"\n",1);
4137dd7cddfSDavid du Colombier 				Bterm(snarffp);
4147dd7cddfSDavid du Colombier 				snarffp = 0;
4157dd7cddfSDavid du Colombier 				if(lastc != '\n') {
4167dd7cddfSDavid du Colombier 					lastc = -1;
4177dd7cddfSDavid du Colombier 					return('\n');
4187dd7cddfSDavid du Colombier 				}
4197dd7cddfSDavid du Colombier 				lastc = -1;
4207dd7cddfSDavid du Colombier 				continue;
4217dd7cddfSDavid du Colombier 			}
4227dd7cddfSDavid du Colombier 			lastc = c;
4237dd7cddfSDavid du Colombier 			c2 = c;
4247dd7cddfSDavid du Colombier 			write(outfd, &c2, 1);
4257dd7cddfSDavid du Colombier 			return(c);
4267dd7cddfSDavid du Colombier 		}
4277dd7cddfSDavid du Colombier 		if(!blocked && host_avail())
4287dd7cddfSDavid du Colombier 			return(rcvchar());
4297dd7cddfSDavid du Colombier 		if(kbdchar > 0) {
4307dd7cddfSDavid du Colombier 			if(blocked)
4317dd7cddfSDavid du Colombier 				resize();
4327dd7cddfSDavid du Colombier 			if(cs->raw) {
4337dd7cddfSDavid du Colombier 				switch(kbdchar){
4347dd7cddfSDavid du Colombier 				case Kup:
4357dd7cddfSDavid du Colombier 					sendfk("up key");
4367dd7cddfSDavid du Colombier 					break;
4377dd7cddfSDavid du Colombier 				case Kdown:
4387dd7cddfSDavid du Colombier 					sendfk("down key");
4397dd7cddfSDavid du Colombier 					break;
4407dd7cddfSDavid du Colombier 				case Kleft:
4417dd7cddfSDavid du Colombier 					sendfk("left key");
4427dd7cddfSDavid du Colombier 					break;
4437dd7cddfSDavid du Colombier 				case Kright:
4447dd7cddfSDavid du Colombier 					sendfk("right key");
4457dd7cddfSDavid du Colombier 					break;
44632e56137SDavid du Colombier 				case Kpgup:
44732e56137SDavid du Colombier 					sendfk("page up");
44832e56137SDavid du Colombier 					break;
44932e56137SDavid du Colombier 				case Kpgdown:
45032e56137SDavid du Colombier 					sendfk("page down");
45132e56137SDavid du Colombier 					break;
45280ee5cbfSDavid du Colombier 				case KF|1:
45380ee5cbfSDavid du Colombier 					sendfk("F1");
45480ee5cbfSDavid du Colombier 					break;
45580ee5cbfSDavid du Colombier 				case KF|2:
45680ee5cbfSDavid du Colombier 					sendfk("F2");
45780ee5cbfSDavid du Colombier 					break;
45880ee5cbfSDavid du Colombier 				case KF|3:
45980ee5cbfSDavid du Colombier 					sendfk("F3");
46080ee5cbfSDavid du Colombier 					break;
46180ee5cbfSDavid du Colombier 				case KF|4:
46280ee5cbfSDavid du Colombier 					sendfk("F4");
46380ee5cbfSDavid du Colombier 					break;
46480ee5cbfSDavid du Colombier 				case KF|5:
46580ee5cbfSDavid du Colombier 					sendfk("F5");
46680ee5cbfSDavid du Colombier 					break;
46780ee5cbfSDavid du Colombier 				case KF|6:
46880ee5cbfSDavid du Colombier 					sendfk("F6");
46980ee5cbfSDavid du Colombier 					break;
47080ee5cbfSDavid du Colombier 				case KF|7:
47180ee5cbfSDavid du Colombier 					sendfk("F7");
47280ee5cbfSDavid du Colombier 					break;
47380ee5cbfSDavid du Colombier 				case KF|8:
47480ee5cbfSDavid du Colombier 					sendfk("F8");
47580ee5cbfSDavid du Colombier 					break;
47680ee5cbfSDavid du Colombier 				case KF|9:
47780ee5cbfSDavid du Colombier 					sendfk("F9");
47880ee5cbfSDavid du Colombier 					break;
47980ee5cbfSDavid du Colombier 				case KF|10:
48080ee5cbfSDavid du Colombier 					sendfk("F10");
48180ee5cbfSDavid du Colombier 					break;
48280ee5cbfSDavid du Colombier 				case KF|11:
48380ee5cbfSDavid du Colombier 					sendfk("F11");
48480ee5cbfSDavid du Colombier 					break;
48580ee5cbfSDavid du Colombier 				case KF|12:
48680ee5cbfSDavid du Colombier 					sendfk("F12");
48780ee5cbfSDavid du Colombier 					break;
48880ee5cbfSDavid du Colombier 				case '\n':
48980ee5cbfSDavid du Colombier 					echobuf[0] = '\r';
49080ee5cbfSDavid du Colombier 					sendnchars(1, echobuf);
49180ee5cbfSDavid du Colombier 					break;
49280ee5cbfSDavid du Colombier 				case '\r':
49380ee5cbfSDavid du Colombier 					echobuf[0] = '\n';
49480ee5cbfSDavid du Colombier 					sendnchars(1, echobuf);
49580ee5cbfSDavid du Colombier 					break;
4967dd7cddfSDavid du Colombier 				default:
4977dd7cddfSDavid du Colombier 					echobuf[0] = kbdchar;
4987dd7cddfSDavid du Colombier 					sendnchars(1, echobuf);
4997dd7cddfSDavid du Colombier 					break;
5007dd7cddfSDavid du Colombier 				}
5017dd7cddfSDavid du Colombier 			} else if(canon(echobuf,kbdchar) == SCROLL) {
5027dd7cddfSDavid du Colombier 				if(!blocked)
5037dd7cddfSDavid du Colombier 					bigscroll();
5047dd7cddfSDavid du Colombier 			} else
5057dd7cddfSDavid du Colombier 				strcat(echo_input,echobuf);
5067dd7cddfSDavid du Colombier 			blocked = 0;
5077dd7cddfSDavid du Colombier 			kbdchar = -1;
5087dd7cddfSDavid du Colombier 			continue;
5097dd7cddfSDavid du Colombier 		}
5107dd7cddfSDavid du Colombier 		curson(wasblocked);	/* turn on cursor while we're waiting */
5117dd7cddfSDavid du Colombier 		do {
5127dd7cddfSDavid du Colombier 			newmouse = 0;
5137dd7cddfSDavid du Colombier 			switch(eread(blocked ? Emouse|Ekeyboard :
5147dd7cddfSDavid du Colombier 					       Emouse|Ekeyboard|Ehost, &e)) {
5157dd7cddfSDavid du Colombier 			case Emouse:
5167dd7cddfSDavid du Colombier 				mouse = e.mouse;
5177dd7cddfSDavid du Colombier 				if(button2() || button3())
5187dd7cddfSDavid du Colombier 					readmenu();
5197dd7cddfSDavid du Colombier 				else if(resize_flag == 0) {
5207dd7cddfSDavid du Colombier 					/* eresized() is triggered by special mouse event */
5217dd7cddfSDavid du Colombier 					newmouse = 1;
5227dd7cddfSDavid du Colombier 				}
5237dd7cddfSDavid du Colombier 				break;
5247dd7cddfSDavid du Colombier 			case Ekeyboard:
5257dd7cddfSDavid du Colombier 				kbdchar = e.kbdc;
5267dd7cddfSDavid du Colombier 				break;
5277dd7cddfSDavid du Colombier 			case Ehost:
5287dd7cddfSDavid du Colombier 				set_host(&e);
5297dd7cddfSDavid du Colombier 				break;
5307dd7cddfSDavid du Colombier 			default:
5317dd7cddfSDavid du Colombier 				perror("protocol violation");
5327dd7cddfSDavid du Colombier 				exits("protocol violation");
5337dd7cddfSDavid du Colombier 			}
5347dd7cddfSDavid du Colombier 		} while(newmouse == 1);
5357dd7cddfSDavid du Colombier 		cursoff();	/* turn cursor back off */
5367dd7cddfSDavid du Colombier 	}
5377dd7cddfSDavid du Colombier }
5387dd7cddfSDavid du Colombier 
5397dd7cddfSDavid du Colombier void
eresized(int new)5407dd7cddfSDavid du Colombier eresized(int new)
5417dd7cddfSDavid du Colombier {
5427dd7cddfSDavid du Colombier 	resize_flag = 1+new;
5437dd7cddfSDavid du Colombier }
5447dd7cddfSDavid du Colombier 
5457dd7cddfSDavid du Colombier void
putenvint(char * name,int x)5467fb4e6f1SDavid du Colombier putenvint(char *name, int x)
5477fb4e6f1SDavid du Colombier {
5487fb4e6f1SDavid du Colombier 	char buf[20];
5497fb4e6f1SDavid du Colombier 
5507fb4e6f1SDavid du Colombier 	snprint(buf, sizeof buf, "%d", x);
5517fb4e6f1SDavid du Colombier 	putenv(name, buf);
5527fb4e6f1SDavid du Colombier }
5537fb4e6f1SDavid du Colombier 
5547fb4e6f1SDavid du Colombier void
exportsize(void)5557dd7cddfSDavid du Colombier exportsize(void)
5567dd7cddfSDavid du Colombier {
5577fb4e6f1SDavid du Colombier 	putenvint("XPIXELS", Dx(screen->r)-2*XMARGIN);
5587fb4e6f1SDavid du Colombier 	putenvint("YPIXELS", Dy(screen->r)-2*XMARGIN);
5597fb4e6f1SDavid du Colombier 	putenvint("LINES", ymax+1);
5607fb4e6f1SDavid du Colombier 	putenvint("COLS", xmax+1);
5617fb4e6f1SDavid du Colombier 	putenv("TERM", term);
5627dd7cddfSDavid du Colombier }
5637dd7cddfSDavid du Colombier 
5647dd7cddfSDavid du Colombier void
resize(void)5657dd7cddfSDavid du Colombier resize(void)
5667dd7cddfSDavid du Colombier {
5677dd7cddfSDavid du Colombier 	if(resize_flag > 1 && getwindow(display, Refnone) < 0){
5687dd7cddfSDavid du Colombier 		fprint(2, "can't reattach to window: %r\n");
5697dd7cddfSDavid du Colombier 		exits("can't reattach to window");
5707dd7cddfSDavid du Colombier 	}
5717dd7cddfSDavid du Colombier 	xmax = (Dx(screen->r)-2*XMARGIN)/CW-1;
5727dd7cddfSDavid du Colombier 	ymax = (Dy(screen->r)-2*YMARGIN)/NS-1;
5737dd7cddfSDavid du Colombier 	if(xmax == 0 || ymax == 0)
5747dd7cddfSDavid du Colombier 		exits("window gone");
5757dd7cddfSDavid du Colombier 	x = 0;
5767dd7cddfSDavid du Colombier 	y = 0;
5777dd7cddfSDavid du Colombier 	yscrmin = 0;
57880ee5cbfSDavid du Colombier 	yscrmax = ymax;
5797dd7cddfSDavid du Colombier 	olines = 0;
5807dd7cddfSDavid du Colombier 	exportsize();
5817dd7cddfSDavid du Colombier 	clear(screen->r);
5827dd7cddfSDavid du Colombier 	resize_flag = 0;
583*21abd8f2SDavid du Colombier 	werrstr("");		/* clear spurious error messages */
5847dd7cddfSDavid du Colombier }
5857dd7cddfSDavid du Colombier 
5867dd7cddfSDavid du Colombier void
setdim(int ht,int wid)58780ee5cbfSDavid du Colombier setdim(int ht, int wid)
58880ee5cbfSDavid du Colombier {
58980ee5cbfSDavid du Colombier 	int fd;
59080ee5cbfSDavid du Colombier 	Rectangle r;
59180ee5cbfSDavid du Colombier 
59280ee5cbfSDavid du Colombier 	if(ht != -1)
59380ee5cbfSDavid du Colombier 		ymax = ht-1;
59480ee5cbfSDavid du Colombier 	if(wid != -1)
59580ee5cbfSDavid du Colombier 		xmax = wid-1;
59680ee5cbfSDavid du Colombier 
59780ee5cbfSDavid du Colombier 	r.min = screen->r.min;
59880ee5cbfSDavid du Colombier 	r.max = addpt(screen->r.min,
59980ee5cbfSDavid du Colombier 			Pt((xmax+1)*CW+2*XMARGIN+2*INSET,
60080ee5cbfSDavid du Colombier 				(ymax+1)*NS+2*YMARGIN+2*INSET));
60180ee5cbfSDavid du Colombier 	fd = open("/dev/wctl", OWRITE);
602*21abd8f2SDavid du Colombier 	if(fd < 0 || fprint(fd, "resize -dx %d -dy %d\n", Dx(r)+2*Borderwidth,
603*21abd8f2SDavid du Colombier 	    Dy(r)+2*Borderwidth) < 0){
60480ee5cbfSDavid du Colombier 		border(screen, r, INSET, bordercol, ZP);
60580ee5cbfSDavid du Colombier 		exportsize();
60680ee5cbfSDavid du Colombier 	}
60780ee5cbfSDavid du Colombier 	if(fd >= 0)
60880ee5cbfSDavid du Colombier 		close(fd);
60980ee5cbfSDavid du Colombier }
61080ee5cbfSDavid du Colombier 
61180ee5cbfSDavid du Colombier void
readmenu(void)6127dd7cddfSDavid du Colombier readmenu(void)
6137dd7cddfSDavid du Colombier {
6147dd7cddfSDavid du Colombier 	if(button3()) {
6157dd7cddfSDavid du Colombier 		menu3.item[1] = ttystate[cs->raw].crnl ? "cr" : "crnl";
6167dd7cddfSDavid du Colombier 		menu3.item[2] = ttystate[cs->raw].nlcr ? "nl" : "nlcr";
6177dd7cddfSDavid du Colombier 		menu3.item[3] = cs->raw ? "cooked" : "raw";
6187dd7cddfSDavid du Colombier 
6197dd7cddfSDavid du Colombier 		switch(emenuhit(3, &mouse, &menu3)) {
6207dd7cddfSDavid du Colombier 		case 0:		/* 24x80 */
62180ee5cbfSDavid du Colombier 			setdim(24, 80);
6227dd7cddfSDavid du Colombier 			return;
6237dd7cddfSDavid du Colombier 		case 1:		/* newline after cr? */
6247dd7cddfSDavid du Colombier 			ttystate[cs->raw].crnl = !ttystate[cs->raw].crnl;
6257dd7cddfSDavid du Colombier 			return;
6267dd7cddfSDavid du Colombier 		case 2:		/* cr after newline? */
6277dd7cddfSDavid du Colombier 			ttystate[cs->raw].nlcr = !ttystate[cs->raw].nlcr;
6287dd7cddfSDavid du Colombier 			return;
6297dd7cddfSDavid du Colombier 		case 3:		/* switch raw mode */
6307dd7cddfSDavid du Colombier 			cs->raw = !cs->raw;
6317dd7cddfSDavid du Colombier 			return;
63280ee5cbfSDavid du Colombier 		case 4:
63380ee5cbfSDavid du Colombier 			exits(0);
6347dd7cddfSDavid du Colombier 		}
6357dd7cddfSDavid du Colombier 		return;
6367dd7cddfSDavid du Colombier 	}
6377dd7cddfSDavid du Colombier 
6387dd7cddfSDavid du Colombier 	menu2.item[5] = pagemode? "scroll": "page";
6397dd7cddfSDavid du Colombier 
6407dd7cddfSDavid du Colombier 	switch(emenuhit(2, &mouse, &menu2)) {
6417dd7cddfSDavid du Colombier 
6427dd7cddfSDavid du Colombier 	case 0:		/* back up */
6437dd7cddfSDavid du Colombier 		if(atend == 0) {
6447dd7cddfSDavid du Colombier 			backc++;
6457dd7cddfSDavid du Colombier 			backup(backc);
6467dd7cddfSDavid du Colombier 		}
6477dd7cddfSDavid du Colombier 		return;
6487dd7cddfSDavid du Colombier 
6497dd7cddfSDavid du Colombier 	case 1:		/* move forward */
6507dd7cddfSDavid du Colombier 		backc--;
6517dd7cddfSDavid du Colombier 		if(backc >= 0)
6527dd7cddfSDavid du Colombier 			backup(backc);
6537dd7cddfSDavid du Colombier 		else
6547dd7cddfSDavid du Colombier 			backc = 0;
6557dd7cddfSDavid du Colombier 		return;
6567dd7cddfSDavid du Colombier 
6577dd7cddfSDavid du Colombier 	case 2:		/* reset */
6587dd7cddfSDavid du Colombier 		backc = 0;
6597dd7cddfSDavid du Colombier 		backup(0);
6607dd7cddfSDavid du Colombier 		return;
6617dd7cddfSDavid du Colombier 
6627dd7cddfSDavid du Colombier 	case 3:		/* clear screen */
6637dd7cddfSDavid du Colombier 		eresized(0);
6647dd7cddfSDavid du Colombier 		return;
6657dd7cddfSDavid du Colombier 
6667dd7cddfSDavid du Colombier 	case 4:		/* send the snarf buffer */
6677dd7cddfSDavid du Colombier 		snarffp = Bopen("/dev/snarf",OREAD);
6687dd7cddfSDavid du Colombier 		return;
6697dd7cddfSDavid du Colombier 
6707dd7cddfSDavid du Colombier 	case 5:		/* pause and clear at end of screen */
6717dd7cddfSDavid du Colombier 		pagemode = 1-pagemode;
6727dd7cddfSDavid du Colombier 		if(blocked && !pagemode) {
6737dd7cddfSDavid du Colombier 			eresized(0);
6747dd7cddfSDavid du Colombier 			blocked = 0;
6757dd7cddfSDavid du Colombier 		}
6767dd7cddfSDavid du Colombier 		return;
6777dd7cddfSDavid du Colombier 	}
6787dd7cddfSDavid du Colombier }
6797dd7cddfSDavid du Colombier 
6807dd7cddfSDavid du Colombier void
backup(int count)6817dd7cddfSDavid du Colombier backup(int count)
6827dd7cddfSDavid du Colombier {
6837dd7cddfSDavid du Colombier 	register n;
6847dd7cddfSDavid du Colombier 	register char *cp;
6857dd7cddfSDavid du Colombier 
6867dd7cddfSDavid du Colombier 	eresized(0);
6877dd7cddfSDavid du Colombier 	n = 3*(count+1)*ymax/4;
6887dd7cddfSDavid du Colombier 	cp = histp;
6897dd7cddfSDavid du Colombier 	atend = 0;
6907dd7cddfSDavid du Colombier 	while (n >= 0) {
6917dd7cddfSDavid du Colombier 		cp--;
6927dd7cddfSDavid du Colombier 		if(cp < hist)
6937dd7cddfSDavid du Colombier 			cp = &hist[HISTSIZ-1];
6947dd7cddfSDavid du Colombier 		if(*cp == '\0') {
6957dd7cddfSDavid du Colombier 			atend = 1;
6967dd7cddfSDavid du Colombier 			break;
6977dd7cddfSDavid du Colombier 		}
6987dd7cddfSDavid du Colombier 		if(*cp == '\n')
6997dd7cddfSDavid du Colombier 			n--;
7007dd7cddfSDavid du Colombier 	}
7017dd7cddfSDavid du Colombier 	cp++;
7027dd7cddfSDavid du Colombier 	if(cp >= &hist[HISTSIZ])
7037dd7cddfSDavid du Colombier 		cp = hist;
7047dd7cddfSDavid du Colombier 	backp = cp;
7057dd7cddfSDavid du Colombier 	nbacklines = ymax-2;
7067dd7cddfSDavid du Colombier }
7077dd7cddfSDavid du Colombier 
7087dd7cddfSDavid du Colombier Point
pt(int x,int y)7097dd7cddfSDavid du Colombier pt(int x, int y)
7107dd7cddfSDavid du Colombier {
7117dd7cddfSDavid du Colombier 	return addpt(screen->r.min, Pt(x*CW+XMARGIN,y*NS+YMARGIN));
7127dd7cddfSDavid du Colombier }
7137dd7cddfSDavid du Colombier 
7147dd7cddfSDavid du Colombier void
scroll(int sy,int ly,int dy,int cy)7157dd7cddfSDavid du Colombier scroll(int sy, int ly, int dy, int cy)	/* source, limit, dest, which line to clear */
7167dd7cddfSDavid du Colombier {
71780ee5cbfSDavid du Colombier 	draw(screen, Rpt(pt(0, dy), pt(xmax+1, dy+ly-sy)), screen, nil, pt(0, sy));
7187dd7cddfSDavid du Colombier 	clear(Rpt(pt(0, cy), pt(xmax+1, cy+1)));
71932e56137SDavid du Colombier 	flushimage(display, 1);
7207dd7cddfSDavid du Colombier }
7217dd7cddfSDavid du Colombier 
7227dd7cddfSDavid du Colombier void
bigscroll(void)7237dd7cddfSDavid du Colombier bigscroll(void)			/* scroll up half a page */
7247dd7cddfSDavid du Colombier {
7257dd7cddfSDavid du Colombier 	int half = ymax/3;
7267dd7cddfSDavid du Colombier 
7277dd7cddfSDavid du Colombier 	if(x == 0 && y == 0)
7287dd7cddfSDavid du Colombier 		return;
7297dd7cddfSDavid du Colombier 	if(y < half) {
7307dd7cddfSDavid du Colombier 		clear(Rpt(pt(0,0),pt(xmax+1,ymax+1)));
7317dd7cddfSDavid du Colombier 		x = y = 0;
7327dd7cddfSDavid du Colombier 		return;
7337dd7cddfSDavid du Colombier 	}
7347dd7cddfSDavid du Colombier 	draw(screen, Rpt(pt(0, 0), pt(xmax+1, ymax+1)), screen, nil, pt(0, half));
7357dd7cddfSDavid du Colombier 	clear(Rpt(pt(0,y-half+1),pt(xmax+1,ymax+1)));
7367dd7cddfSDavid du Colombier 	y -= half;
7377dd7cddfSDavid du Colombier 	if(olines)
7387dd7cddfSDavid du Colombier 		olines -= half;
73932e56137SDavid du Colombier 	flushimage(display, 1);
7407dd7cddfSDavid du Colombier }
7417dd7cddfSDavid du Colombier 
7427dd7cddfSDavid du Colombier int
number(char * p,int * got)74380ee5cbfSDavid du Colombier number(char *p, int *got)
7447dd7cddfSDavid du Colombier {
7457dd7cddfSDavid du Colombier 	int c, n = 0;
7467dd7cddfSDavid du Colombier 
74780ee5cbfSDavid du Colombier 	if(got)
74880ee5cbfSDavid du Colombier 		*got = 0;
74980ee5cbfSDavid du Colombier 	while ((c = get_next_char()) >= '0' && c <= '9'){
75080ee5cbfSDavid du Colombier 		if(got)
75180ee5cbfSDavid du Colombier 			*got = 1;
7527dd7cddfSDavid du Colombier 		n = n*10 + c - '0';
75380ee5cbfSDavid du Colombier 	}
7547dd7cddfSDavid du Colombier 	*p = c;
7557dd7cddfSDavid du Colombier 	return(n);
7567dd7cddfSDavid du Colombier }
7577dd7cddfSDavid du Colombier 
7587dd7cddfSDavid du Colombier /* stubs */
7597dd7cddfSDavid du Colombier 
7607dd7cddfSDavid du Colombier void
sendnchars(int n,char * p)7617dd7cddfSDavid du Colombier sendnchars(int n,char *p)
7627dd7cddfSDavid du Colombier {
7637dd7cddfSDavid du Colombier 	sendnchars2(n, p);
7647dd7cddfSDavid du Colombier 	p[n+1] = 0;
7657dd7cddfSDavid du Colombier }
7667dd7cddfSDavid du Colombier 
7677dd7cddfSDavid du Colombier void
sendnchars2(int n,char * p)7687dd7cddfSDavid du Colombier sendnchars2(int n,char *p)
7697dd7cddfSDavid du Colombier {
7707dd7cddfSDavid du Colombier 	if(write(outfd,p,n) < 0) {
7717dd7cddfSDavid du Colombier 		close(outfd);
7727dd7cddfSDavid du Colombier 		close(0);
7737dd7cddfSDavid du Colombier 		close(1);
7747dd7cddfSDavid du Colombier 		close(2);
7757dd7cddfSDavid du Colombier 		exits("write");
7767dd7cddfSDavid du Colombier 	}
7777dd7cddfSDavid du Colombier }
7787dd7cddfSDavid du Colombier 
7797dd7cddfSDavid du Colombier int
host_avail(void)7807dd7cddfSDavid du Colombier host_avail(void)
7817dd7cddfSDavid du Colombier {
7827dd7cddfSDavid du Colombier 	return(*echop || ((hostp - host_buf) < hostlength));
7837dd7cddfSDavid du Colombier }
7847dd7cddfSDavid du Colombier 
7857dd7cddfSDavid du Colombier int
rcvchar(void)7867dd7cddfSDavid du Colombier rcvchar(void)
7877dd7cddfSDavid du Colombier {
7887dd7cddfSDavid du Colombier 	int c;
7897dd7cddfSDavid du Colombier 	if(*echop) {
7907dd7cddfSDavid du Colombier 		c = *echop++;
7917dd7cddfSDavid du Colombier 		if(!*echop) {
7927dd7cddfSDavid du Colombier 			echop = echo_input;
7937dd7cddfSDavid du Colombier 			*echop = 0;
7947dd7cddfSDavid du Colombier 		}
7957dd7cddfSDavid du Colombier 		return c;
7967dd7cddfSDavid du Colombier 	}
7977dd7cddfSDavid du Colombier 	return *hostp++;
7987dd7cddfSDavid du Colombier }
7997dd7cddfSDavid du Colombier 
8007dd7cddfSDavid du Colombier void
set_host(Event * e)8017dd7cddfSDavid du Colombier set_host(Event *e)
8027dd7cddfSDavid du Colombier {
8037dd7cddfSDavid du Colombier 	hostlength = e->n;
8047dd7cddfSDavid du Colombier 	if(hostlength > host_bsize) {
8057dd7cddfSDavid du Colombier 		host_bsize *= 2;
8067dd7cddfSDavid du Colombier 		host_buf = realloc(host_buf,host_bsize);
8077dd7cddfSDavid du Colombier 	}
8087dd7cddfSDavid du Colombier 	hostp = host_buf;
8097dd7cddfSDavid du Colombier 	memmove(host_buf,e->data,hostlength);
8107dd7cddfSDavid du Colombier 	host_buf[hostlength]=0;
8117dd7cddfSDavid du Colombier }
8127dd7cddfSDavid du Colombier 
8137dd7cddfSDavid du Colombier void
ringbell(void)8147dd7cddfSDavid du Colombier ringbell(void){
8157dd7cddfSDavid du Colombier }
8167dd7cddfSDavid du Colombier 
8177dd7cddfSDavid du Colombier int
alnum(int c)8187dd7cddfSDavid du Colombier alnum(int c)
8197dd7cddfSDavid du Colombier {
8207dd7cddfSDavid du Colombier 	if(c >= 'a' && c <= 'z')
8217dd7cddfSDavid du Colombier 		return 1;
8227dd7cddfSDavid du Colombier 	if(c >= 'A' && c <= 'Z')
8237dd7cddfSDavid du Colombier 		return 1;
8247dd7cddfSDavid du Colombier 	if(c >= '0' && c <= '9')
8257dd7cddfSDavid du Colombier 		return 1;
8267dd7cddfSDavid du Colombier 	return 0;
8277dd7cddfSDavid du Colombier }
8287dd7cddfSDavid du Colombier 
8297dd7cddfSDavid du Colombier void
escapedump(int fd,uchar * str,int len)8307dd7cddfSDavid du Colombier escapedump(int fd,uchar *str,int len)
8317dd7cddfSDavid du Colombier {
8327dd7cddfSDavid du Colombier 	int i;
8337dd7cddfSDavid du Colombier 
8347dd7cddfSDavid du Colombier 	for(i = 0; i < len; i++) {
8357dd7cddfSDavid du Colombier 		if((str[i] < ' ' || str[i] > '\177') &&
8367dd7cddfSDavid du Colombier 			str[i] != '\n' && str[i] != '\t') fprint(fd,"^%c",str[i]+64);
8377dd7cddfSDavid du Colombier 		else if(str[i] == '\177') fprint(fd,"^$");
8387dd7cddfSDavid du Colombier 		else if(str[i] == '\n') fprint(fd,"^J\n");
8397dd7cddfSDavid du Colombier 		else fprint(fd,"%c",str[i]);
8407dd7cddfSDavid du Colombier 	}
8417dd7cddfSDavid du Colombier }
8427dd7cddfSDavid du Colombier 
8437dd7cddfSDavid du Colombier void
funckey(int key)8447dd7cddfSDavid du Colombier funckey(int key)
8457dd7cddfSDavid du Colombier {
8467dd7cddfSDavid du Colombier 	if(key >= NKEYS)
8477dd7cddfSDavid du Colombier 		return;
8487dd7cddfSDavid du Colombier 	if(fk[key].name == 0)
8497dd7cddfSDavid du Colombier 		return;
8507dd7cddfSDavid du Colombier 	sendnchars2(strlen(fk[key].sequence), fk[key].sequence);
8517dd7cddfSDavid du Colombier }
8527dd7cddfSDavid du Colombier 
85380ee5cbfSDavid du Colombier 
8547dd7cddfSDavid du Colombier void
drawstring(Point p,char * str,int attr)8557fb4e6f1SDavid du Colombier drawstring(Point p, char *str, int attr)
8567dd7cddfSDavid du Colombier {
8577fb4e6f1SDavid du Colombier 	int i;
8587fb4e6f1SDavid du Colombier 	Image *txt, *bg, *tmp;
8597dd7cddfSDavid du Colombier 
8607fb4e6f1SDavid du Colombier 	txt = fgcolor;
8617fb4e6f1SDavid du Colombier 	bg = bgcolor;
8627fb4e6f1SDavid du Colombier 	if(attr & TReverse){
8637fb4e6f1SDavid du Colombier 		tmp = txt;
8647fb4e6f1SDavid du Colombier 		txt = bg;
8657fb4e6f1SDavid du Colombier 		bg = tmp;
86632e56137SDavid du Colombier 	}
8677fb4e6f1SDavid du Colombier 	if(attr & THighIntensity){
8687fb4e6f1SDavid du Colombier 		for(i=0; i<8; i++)
8697fb4e6f1SDavid du Colombier 			if(txt == colors[i])
8707fb4e6f1SDavid du Colombier 				txt = hicolors[i];
87132e56137SDavid du Colombier 	}
87280ee5cbfSDavid du Colombier 
8737fb4e6f1SDavid du Colombier 	draw(screen, Rpt(p, addpt(p, stringsize(font, str))), bg, nil, p);
8747fb4e6f1SDavid du Colombier 	string(screen, p, txt, ZP, font, str);
8757dd7cddfSDavid du Colombier }
876