9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: Micah Stetson <micah@cnm-vra.com>
To: 9fans@cse.psu.edu
Subject: Re: [9fans] The VT saga
Date: Tue,  7 Nov 2000 06:32:27 -0800	[thread overview]
Message-ID: <20001107063227.A21140@cnm-vra.com> (raw)
In-Reply-To: <200009110945.LAA19698@chuckle.iba.co.za>; from lucio@proxima.alt.za on Mon, Sep 11, 2000 at 11:41:21AM +0000

[-- Attachment #1: Type: text/plain, Size: 1228 bytes --]

I took a look at vt tonight and while vttest still just turns
up its nose at me, it looks like I've eliminated most of the
real problems I had with Mutt and vi.  There are mainly
three changes.

First, I finally think I've got scroll() right.  Lucio's
previous patch said
> /mnt/wrap/sys/src/cmd/vt/main.c:577 c /sys/src/cmd/vt/main.c:584
> < 	draw(screen, Rpt(pt(0, dy), pt(xmax+1, ly-sy)), screen, nil, pt(0, sy));
> ---
> > 	draw(screen, Rpt(pt(0, dy), pt(xmax+1, ly+1)), screen, nil, pt(0, sy));
but it should really have dy+ly-sy in there.

Second, I made the delete to end of line and delete to end of
screen stuff work like the vt100 user's guide says it should.

Last, I changed yscrmin and yscrmax so that they are always the
beginning and end of the scrolling region even when that region
is the whole screen.  That got rid of a bunch of lines that
looked like
	M = yscrmax ? yscrmax : ymax;
Maybe there was a good reason for doing it the other way, but
I don't see it.

Anyway, attached are my current in-progress versions of vt.c
and main.c from /sys/src/cmd/vt.  They do not include the
patch Lucio posted to this list a few weeks back.  I hope
this is helpful to somebody.

Micah



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: main.c --]
[-- Type: text/x-csrc, Size: 12856 bytes --]

#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",
	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;
Menu	menu2;
Menu	menu3;
char	*histp;
char	hist[HISTSIZ];
int	yscrmin, yscrmax;

Image	*text;
Image	*background;
Image	*bordercol;
Image	*cursback;
Image	*red;

/* terminal control */
struct ttystate ttystate[2] = { {0, 1}, {0,0} };

int	NS;
int	CW;
Consstate *cs;
Mouse	mouse;

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;

/* 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);
char *term;
struct funckey *fk;

int	debug;

void
main(int argc, char **argv)
{
	initialize(argc, argv);
	emulate();
}

void
initialize(int argc, char **argv)
{
	int dayglo = 1;

	rfork(RFENVG|RFNAMEG|RFNOTEG);

	term = "vt100";
	fk = vt100fk;
	ARGBEGIN{
	case '2':
		term = "vt220";
		fk = vt220fk;
		break;
	case 's': /* for sape */
		dayglo = 0;
		break;
	}ARGEND;

	host_buf = malloc(host_bsize);
	hostp = host_buf;
	hostlength = 0;

	if(initdraw(0,0,term) < 0){
		fprint(2, "%s: initdraw failed: %r\n", term);
		exits("initdraw");
	}
	ebegin(Ehost);

	histp = hist;
	menu2.item = menutext2;
	menu3.item = menutext3;
	pagemode = 0;
	blocked = 0;
	NS = font->height ;
	CW = stringwidth(font, "m");
	text = allocimage(display, Rect(0,0,1,1), screen->chan, 1, dayglo?0x00F0F0F0:0);
	background = allocimage(display, Rect(0,0,1,1), screen->chan, 1, dayglo?0x33333333:-1);
	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);
	red =  allocimage(display, Rect(0, 0, CW+1, NS+1), screen->chan, 1, DRed);

	eresized(0);

	if(argc > 0) {
		sendnchars(strlen(argv[0]),argv[0]);
		sendnchars(1,"\n");
	}
}

void
clear(Rectangle r)
{
	draw(screen, r, background, nil, ZP);
}

void
newline(void)
{
	nbacklines--;
	if(y >= yscrmax) {
		y = yscrmax;
		if(pagemode && olines >= yscrmax) {
			blocked = 1;
			return;
		}
		scroll(yscrmin+1, yscrmax+1, yscrmin, yscrmax);
	} else
		y++;
	olines++;
}

void
curson(int bl)
{
	Image *col;

	draw(cursback, cursback->r, screen, nil, subpt(pt(x, y),Pt(1,1)));
	if(bl)
		col = red;
	else
		col = bordercol;
	border(screen, Rpt(subpt(pt(x, y), Pt(1, 1)), addpt(pt(x, y), Pt(CW,NS))),
		2, col, ZP);
}

void
cursoff(void)
{
	draw(screen, Rpt(subpt(pt(x, y), Pt(1, 1)), addpt(pt(x, y), Pt(CW,NS))),
		cursback, nil, cursback->r.min);
}

int
get_next_char(void)
{
	int c = peekc;
	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 = waitchar();
	}
	*histp++ = c;
	if(histp >= &hist[HISTSIZ])
		histp = hist;
	*histp = '\0';
	return(c);
}

int
canon(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);
}

void
sendfk(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;
		}
}

int
waitchar(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;
				default:
					echobuf[0] = kbdchar;
					sendnchars(1, echobuf);
					break;
				}
			} else if(canon(echobuf,kbdchar) == SCROLL) {
				if(!blocked)
					bigscroll();
			} else
				strcat(echo_input,echobuf);
			blocked = 0;
			kbdchar = -1;
			continue;
		}
		curson(wasblocked);	/* turn on cursor while we're waiting */
		do {
			newmouse = 0;
			switch(eread(blocked ? Emouse|Ekeyboard : 
					       Emouse|Ekeyboard|Ehost, &e)) {
			case Emouse:
				mouse = e.mouse;
				if(button2() || button3())
					readmenu();
				else if(resize_flag == 0) {
					/* eresized() is triggered by special mouse event */
					newmouse = 1;
				}
				break;
			case Ekeyboard:
				kbdchar = e.kbdc;
				break;
			case Ehost:
				set_host(&e);
				break;
			default:
				perror("protocol violation");
				exits("protocol violation");
			}
		} while(newmouse == 1);
		cursoff();	/* turn cursor back off */
	}
	return 1;		/* to shut up compiler */
}

void
eresized(int new)
{
	resize_flag = 1+new;
}

void
exportsize(void)
{
	int	fd;
	char	buf[10];

	if((fd = create("/env/LINES", OWRITE, 0644)) > 0) {
		sprint(buf,"%d",ymax+1);
		write(fd,buf,strlen(buf));
		close(fd);
	}
	if((fd = create("/env/COLS", OWRITE, 0644)) > 0) {
		sprint(buf,"%d",xmax+1);
		write(fd,buf,strlen(buf));
		close(fd);
	}
	if((fd = create("/env/TERM", OWRITE, 0644)) > 0) {
		fprint(fd, "%s", term);
		close(fd);
	}
}

void
resize(void)
{
	if(resize_flag > 1 && getwindow(display, Refnone) < 0){
		fprint(2, "can't reattach to window: %r\n");
		exits("can't reattach to window");
	}
	xmax = (Dx(screen->r)-2*XMARGIN)/CW-1;
	ymax = (Dy(screen->r)-2*YMARGIN)/NS-1;
	if(xmax == 0 || ymax == 0)
		exits("window gone");
	x = 0;
	y = 0;
	yscrmin = 0;
	yscrmax = ymax;
	olines = 0;
	exportsize();
	clear(screen->r);
	resize_flag = 0;
}

void
readmenu(void)
{
	Rectangle r;
	int fd;

	if(button3()) {
		menu3.item[1] = ttystate[cs->raw].crnl ? "cr" : "crnl";
		menu3.item[2] = ttystate[cs->raw].nlcr ? "nl" : "nlcr";
		menu3.item[3] = cs->raw ? "cooked" : "raw";

		switch(emenuhit(3, &mouse, &menu3)) {
		case 0:		/* 24x80 */
			r.min = screen->r.min;
			r.max = addpt(screen->r.min,
				Pt(80*CW+2*XMARGIN+2*INSET,
				24*NS+2*YMARGIN+2*INSET));
			fd = open("/dev/wctl", OWRITE);
			if(fd < 0 || fprint(fd, "resize -dx %d -dy %d\n", Dx(r)+2*Borderwidth, Dy(r)+2*Borderwidth) < 0){
				border(screen, r, INSET, bordercol, ZP);
				xmax = 79;
				ymax = 23;
				exportsize();
			}
			if(fd >= 0)
				close(fd);
			return;
		case 1:		/* newline after cr? */
			ttystate[cs->raw].crnl = !ttystate[cs->raw].crnl;
			return;
		case 2:		/* cr after newline? */
			ttystate[cs->raw].nlcr = !ttystate[cs->raw].nlcr;
			return;
		case 3:		/* switch raw mode */
			cs->raw = !cs->raw;
			return;
		}
		return;
	}

	menu2.item[5] = pagemode? "scroll": "page";

	switch(emenuhit(2, &mouse, &menu2)) {

	case 0:		/* back up */
		if(atend == 0) {
			backc++;
			backup(backc);
		}
		return;

	case 1:		/* move forward */
		backc--;
		if(backc >= 0)
			backup(backc);
		else
			backc = 0;
		return;

	case 2:		/* reset */
		backc = 0;
		backup(0);
		return;

	case 3:		/* clear screen */
		eresized(0);
		return;

	case 4:		/* send the snarf buffer */
		snarffp = Bopen("/dev/snarf",OREAD);
		return;

	case 5:		/* pause and clear at end of screen */
		pagemode = 1-pagemode;
		if(blocked && !pagemode) {
			eresized(0);
			blocked = 0;
		}
		return;
	}
}

void
backup(int count)
{
	register n;
	register char *cp;

	eresized(0);
	n = 3*(count+1)*ymax/4;
	cp = histp;
	atend = 0;
	while (n >= 0) {
		cp--;
		if(cp < hist)
			cp = &hist[HISTSIZ-1];
		if(*cp == '\0') {
			atend = 1;
			break;
		}
		if(*cp == '\n')
			n--;
	}
	cp++;
	if(cp >= &hist[HISTSIZ])
		cp = hist;
	backp = cp;
	nbacklines = ymax-2;
}

Point
pt(int x, int y)
{
	return addpt(screen->r.min, Pt(x*CW+XMARGIN,y*NS+YMARGIN));
}

void
scroll(int sy, int ly, int dy, int cy)	/* source, limit, dest, which line to clear */
{
	draw(screen, Rpt(pt(0, dy), pt(xmax+1, dy+ly-sy)), screen, nil, pt(0, sy));
	clear(Rpt(pt(0, cy), pt(xmax+1, cy+1)));
}

void
bigscroll(void)			/* scroll up half a page */
{
	int half = ymax/3;

	if(x == 0 && y == 0)
		return;
	if(y < half) {
		clear(Rpt(pt(0,0),pt(xmax+1,ymax+1)));
		x = y = 0;
		return;
	}
	draw(screen, Rpt(pt(0, 0), pt(xmax+1, ymax+1)), screen, nil, pt(0, half));
	clear(Rpt(pt(0,y-half+1),pt(xmax+1,ymax+1)));
	y -= half;
	if(olines)
		olines -= half;
}

int
number(char *p)
{
	int c, n = 0;

	while ((c = get_next_char()) >= '0' && c <= '9')
		n = n*10 + c - '0';
	*p = c;
	return(n);
}

/* stubs */

void
sendnchars(int n,char *p)
{
	sendnchars2(n, p);
	p[n+1] = 0;
}

void
sendnchars2(int n,char *p)
{
	if(write(outfd,p,n) < 0) {
		close(outfd);
		close(0);
		close(1);
		close(2);
		exits("write");
	}
}

int
host_avail(void)
{
	return(*echop || ((hostp - host_buf) < hostlength));
}

int
rcvchar(void)
{
	int c;
	if(*echop) {
		c = *echop++;
		if(!*echop) {
			echop = echo_input;	
			*echop = 0;
		}
		return c;
	}
	return *hostp++;
}

void
set_host(Event *e)
{
	hostlength = e->n;
	if(hostlength > host_bsize) {
		host_bsize *= 2;
		host_buf = realloc(host_buf,host_bsize);
	}
	hostp = host_buf;
	memmove(host_buf,e->data,hostlength);
	host_buf[hostlength]=0;
}

void
ringbell(void){
}

int
alnum(int c)
{
	if(c >= 'a' && c <= 'z')
		return 1;
	if(c >= 'A' && c <= 'Z')
		return 1;
	if(c >= '0' && c <= '9')
		return 1;
	return 0;
}

void
escapedump(int fd,uchar *str,int len)
{
	int i;

	for(i = 0; i < len; i++) {
		if((str[i] < ' ' || str[i] > '\177') && 
			str[i] != '\n' && str[i] != '\t') fprint(fd,"^%c",str[i]+64);
		else if(str[i] == '\177') fprint(fd,"^$");
		else if(str[i] == '\n') fprint(fd,"^J\n");
		else fprint(fd,"%c",str[i]);
	}
}

void
funckey(int key)
{
	if(key >= NKEYS)
		return;
	if(fk[key].name == 0)
		return;
	sendnchars2(strlen(fk[key].sequence), fk[key].sequence);
}

void
drawstring(Point p, char *str, int standout)
{
	Image *txt, *bg;

	txt = text;
	bg = background;
	if(standout){
		txt = background;
		bg = text;
	}
	draw(screen, Rpt(p, addpt(p, stringsize(font, str))), bg, nil, p);
	string(screen, p, txt, ZP, font, str);
}

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: vt.c --]
[-- Type: text/x-csrc, Size: 9949 bytes --]

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <bio.h>
#include <ctype.h>
#include "cons.h"

struct funckey vt100fk[NKEYS] = {
	{ "up key",		"\033OA", },
	{ "down key",		"\033OB", },
	{ "left key",		"\033OD", },
	{ "right key",		"\033OC", },
};

struct funckey vt220fk[NKEYS] = {
	{ "up key",		"\033[A", },
	{ "down key",		"\033[B", },
	{ "left key",		"\033[D", },
	{ "right key",		"\033[C", },
};

char gmap[256] = {
	['_']	' ',	/* blank */
	['\\']	'*',	/* diamond */
	['a']	'X',	/* checkerboard */
	['b']	'\t',	/* HT */
	['c']	'\x0C',	/* FF */
	['d']	'\r',	/* CR */
	['e']	'\n',	/* LF */
	['f']	'o',	/* degree */
	['g']	'+',	/* plus/minus */
	['h']	'\n',	/* NL, but close enough */
	['i']	'\v',	/* VT */
	['j']	'+',	/* lower right corner */
	['k']	'+',	/* upper right corner */
	['l']	'+',	/* upper left corner */
	['m']	'+',	/* lower left corner */
	['n']	'+',	/* crossing lines */
	['o']	'-',	/* horiz line - scan 1 */
	['p']	'-',	/* horiz line - scan 3 */
	['q']	'-',	/* horiz line - scan 5 */
	['r']	'-',	/* horiz line - scan 7 */
	['s']	'-',	/* horiz line - scan 9 */
	['t']	'+',	/* |-   */
	['u']	'+',	/* -| */
	['v']	'+',	/* upside down T */
	['w']	'+',	/* rightside up T */
	['x']	'|',	/* vertical bar */
	['y']	'<',	/* less/equal */
	['z']	'>',	/* gtr/equal */
	['{']	'p',	/* pi */
	['|']	'!',	/* not equal */
	['}']	'L',	/* pound symbol */
	['~']	'.',	/* centered dot: · */
};

void
emulate(void)
{
	char buf[BUFS+1];
	int n;
	int c;
	int standout;
	int operand, prevOperand;
	int savex, savey;
	int isgraphics;
	int g0set, g1set;

	standout = 0;
	isgraphics = 0;
	g0set = 'B';	/* US ASCII */
	g1set = 'B';	/* US ASCII */
	savex = savey = 0;
	yscrmin = 0;
	yscrmax = ymax;

	for (;;) {
		if (y > ymax) {
			x = 0;
			newline();
		}
		buf[0] = get_next_char();
		buf[1] = '\0';
		switch(buf[0]) {

		case '\000':
		case '\001':
		case '\002':
		case '\003':
		case '\004':
		case '\005':
		case '\006':
			break;

		case '\007':		/* bell */
			ringbell();
			break;

		case '\010':		/* backspace */
			if (x > 0)
				--x;
			break;

		case '\011':		/* tab modulo 8 */
			x = (x|7)+1;
			break;

		case '\012':		/* linefeed */
		case '\013':
		case '\014':
			newline();
			standout = 0;
			if (ttystate[cs->raw].nlcr)
				x = 0;
			break;

		case '\015':		/* carriage return */
			x = 0;
			standout = 0;
			if (ttystate[cs->raw].crnl)
				newline();
			break;

		case '\016':	/* SO: invoke G1 char set */
			isgraphics = (isdigit(g1set));
			break;
		case '\017':	/* SI: invoke G0 char set */
			isgraphics = (isdigit(g0set));
			break;

		case '\020':	/* DLE */
		case '\021':	/* DC1 */
		case '\022':	/* XON */
		case '\023':	/* DC3 */
		case '\024':	/* XOFF */
		case '\025':	/* NAK */
		case '\026':	/* SYN */
		case '\027':	/* ETB */
		case '\030':	/* CAN: cancel escape sequence */
		case '\031':	/* EM: cancel escape sequence, display checkerboard */
		case '\032':	/* SUB: same as CAN */
			break;
		/* ESC, \033, is handled below */
		case '\034':	/* FS */
		case '\035':	/* GS */
		case '\036':	/* RS */
		case '\037':	/* US */
			break;
		case '\177':	/* delete: ignored */
			break;

		case '\033':
			switch(get_next_char()){
			/*
			 * 7 - save cursor position.
			 */
			case '7':
				savex = x;
				savey = y;
				break;

			/*
			 * 8 - restore cursor position.
			 */
			case '8':
				x = savex;
				y = savey;
				break;

			/*
			 * Received c.  Reset terminal.
			 */
			case 'c':
				break;

			/*
			 * Received D.  Active position down a line, scroll if at bottom margin.
			 */
			case 'D':
				if(++y > yscrmax) {
					y = yscrmax;
					scroll(yscrmin+1, yscrmax+1, yscrmin, yscrmax);
				}
				break;

			/*
			 * Received E.  Active position to start of next line, scroll if at bottom margin.
			 */
			case 'E':
				x = 0;
				if(++y > yscrmax) {
					y = yscrmax;
					scroll(yscrmin+1, yscrmax+1, yscrmin, yscrmax);
				}
				break;

			/*
			 * Received M.  Active position up a line, scroll if at top margin..
			 */
			case 'M':
				if(--y < yscrmin) {
					y = yscrmin;
					scroll(yscrmin, yscrmax, yscrmin+1, yscrmin);
				}
				break;

			/*
			 * Z - Identification.  The terminal
			 * emulator will return the response
			 * code for a generic VT100.
			 */
			case 'Z':
			Ident:
				sendnchars2(5, "\033[?6c");
				break;

			/*
			 * H - go home. (No, I think this sets a horizontal tab stop.)
			 */
			case 'H':
				// x = y = 0;
				break;

			/*
			 * > - set numeric keypad mode on
			 */
			case '>':
				break;

			/*
			 * = - set numeric keypad mode off
			 */
			case '=':
				break;

			/*
			 * # - Takes a one-digit argument that 
			 * we need to snarf away.
			 */
			case '#':
				get_next_char();
				break;

			/*
			 * ( - switch G0 character set
			 */
			case '(':
				g0set = get_next_char();
				break;

			/*
			 * - switch G1 character set
			 */
			case ')':
				g1set = get_next_char();
				break;

			/*
			 * Received left bracket.
			 */
			case '[':
				/*
				 * A semi-colon or ? delimits arguments.  Only keep one
				 * previous argument (plus the current one) around.
				 */
				operand = number(buf);
				prevOperand = 0;
				while(buf[0] == ';' || buf[0] == '?'){
					prevOperand = operand;
					operand = number(buf);
				}

				/*
				 * do escape2 stuff
				 */
				switch(buf[0]){
					/*
					 * c - same as ESC Z: who are you?
					 */
					case 'c':
						goto Ident;

					/*
					 * l - clear various options.
					 */
					case 'l':
						break;

					/*
					 * h - set various options.
					 */
					case 'h':
						break;

					/*
					 * A - cursor up.
					 */
					case 'A':
						if(operand == 0)
							operand = 1;
						y -= operand;
						if(y < 0)
							y = 0;
						olines -= operand;
						if(olines < 0)
							olines = 0;
						break;

					/*
					 * B - cursor down
					 */
					case 'B':
						if(operand == 0)
							operand = 1;
						y += operand;
						if(y > ymax)
							y=ymax;
						break;
					
					/*
					 * C - cursor right.
					 */
					case 'C':
						if(operand == 0)
							operand = 1;
						x += operand;
						/*
						 * VT-100-UG says not to go past the
						 * right margin.
						 */
						if(x > xmax)
							x=xmax;
						break;

					/*
					 * D - cursor left
					 */
					case 'D':
						if(operand == 0)
							operand = 1;
						x -= operand;
						if(x < 0)
							x = 0;
						break;

					/*
					 * H and f - cursor motion.  operand is the column
					 * and prevOperand is the row, origin 1.
					 */
					case 'H':
					case 'f':
						x = operand - 1;
						if(x < 0)
							x = 0;
						if(x > xmax)
							x = xmax;
						y = prevOperand - 1;
						if(y < 0)
							y = 0;
						if(y > ymax)
							y = ymax;
						break;

					/*
					 * J - clear some or all of the display.
					 */
					case 'J':
						switch (operand) {
							/*
							 * operand 2:  whole screen.
							 */
							case 2:
								clear(Rpt(pt(0, 0), pt(xmax+1, ymax+1)));
								break;
							/*
							 * operand 1: start of screen to active position, inclusive.
							 */
							case 1:
								clear(Rpt(pt(0, 0), pt(x, ymax+1)));
								clear(Rpt(pt(0, y), pt(x+1, y+1)));
								break;
							/*
							 * Default:  active position to end of screen, inclusive.
							 */
							default:
								clear(Rpt(pt(x, y), pt(xmax+1, y+1)));
								clear(Rpt(pt(0, y+1), pt(xmax+1, ymax+1)));
								break;
						}
						break;

					/*
					 * K - clear some or all of the line.
					 */
					case 'K':
						switch (operand) {
							/*
							 * operand 2: whole line.
							 */
							case 2:
								clear(Rpt(pt(x, y), pt(xmax+1, y+1)));
								break;
							/*
							 * operand 1: start of line to active position, inclusive.
							 */
							case 1:
								clear(Rpt(pt(0, y), pt(x+1, y+1)));
								break;
							/*
							 * Default: active position to end of line, inclusive.
							 */
							default:
								clear(Rpt(pt(x, y), pt(xmax+1, y+1)));
								break;
						}
						break;

					/*
					 * L - insert a line at cursor position
					 */
					case 'L':
						scroll(y, yscrmax, y+1, y);
						break;

					/*
					 * M - delete a line at the cursor position
					 */
					case 'M':
						scroll(y+1, yscrmax+1, y, yscrmax);
						break;

					/*
					 * m - change character attributes.
					 *	Attributes are:
					 *	0	Attributes off
					 *	1	Bold or increased intensity
					 *	4	Underscore
					 *	5	Blink
					 *	7	Negative (reverse) image
					 */
					case 'm':
						standout = operand;
						break;

					/*
					 * r - change scrolling region.  prevOperand is
					 * min scrolling region and operand is max
					 * scrolling region.
					 */
					case 'r':
						yscrmin = prevOperand-1;
						yscrmax = operand-1;
						if (yscrmax == 0)
							yscrmax = ymax;
						break;

					/*
					 * Anything else we ignore for now...
					 */
					default:
						break;
				}

				break;

			/*
			 * Ignore other commands.
			 */
			default:
				break;

			}
			break;

		default:		/* ordinary char */
			if(isgraphics && gmap[(uchar) buf[0]])
				buf[0] = gmap[(uchar) buf[0]];

			/* line wrap */
			if (x > xmax){
				x = 0;
				newline();
			}
			n = 1;
			c = 0;
			while (!cs->raw && host_avail() && x+n<=xmax && n<BUFS
			    && (c = get_next_char())>=' ' && c<'\177') {
				buf[n++] = c;
				c = 0;
			}
			buf[n] = 0;
//			clear(Rpt(pt(x,y), pt(x+n, y+1)));
			drawstring(pt(x, y), buf, standout);
			x += n;
			peekc = c;
			break;
		}
	}
}

  reply	other threads:[~2000-11-07 14:32 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-09-11  9:41 lucio
2000-11-07 14:32 ` Micah Stetson [this message]
  -- strict thread matches above, loose matches on Subject: below --
2000-11-10 14:37 presotto
2000-11-08 22:57 presotto
2000-11-09  4:27 ` Lucio De Re
2000-11-10  1:05   ` Micah Stetson
2000-11-10  4:14     ` Lucio De Re
2000-09-10 16:25 Lucio De Re
2000-09-10 16:37 ` Lucio De Re

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20001107063227.A21140@cnm-vra.com \
    --to=micah@cnm-vra.com \
    --cc=9fans@cse.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).