xref: /plan9-contrib/sys/src/cmd/unix/drawterm/kern/term.c (revision 391922e8ae3ae1e5fda2cceb3bd60377fd86fcf6)
18ccd4a63SDavid du Colombier #include	"u.h"
28ccd4a63SDavid du Colombier #include	"lib.h"
38ccd4a63SDavid du Colombier #include	"dat.h"
48ccd4a63SDavid du Colombier #include	"fns.h"
58ccd4a63SDavid du Colombier #include	"error.h"
68ccd4a63SDavid du Colombier 
78ccd4a63SDavid du Colombier #include	<draw.h>
88ccd4a63SDavid du Colombier #include	<memdraw.h>
98ccd4a63SDavid du Colombier #include	"screen.h"
108ccd4a63SDavid du Colombier 
118ccd4a63SDavid du Colombier #define	MINX	8
128ccd4a63SDavid du Colombier #define	Backgnd		0xFF	/* white */
138ccd4a63SDavid du Colombier 
148ccd4a63SDavid du Colombier 		Memsubfont	*memdefont;
158ccd4a63SDavid du Colombier 
168ccd4a63SDavid du Colombier struct{
178ccd4a63SDavid du Colombier 	Point	pos;
188ccd4a63SDavid du Colombier 	int	bwid;
198ccd4a63SDavid du Colombier }out;
208ccd4a63SDavid du Colombier 
218ccd4a63SDavid du Colombier Lock	screenlock;
228ccd4a63SDavid du Colombier 
238ccd4a63SDavid du Colombier Memimage *conscol;
248ccd4a63SDavid du Colombier Memimage *back;
258ccd4a63SDavid du Colombier extern Memimage *gscreen;
268ccd4a63SDavid du Colombier 
278ccd4a63SDavid du Colombier static Rectangle flushr;
288ccd4a63SDavid du Colombier static Rectangle window;
298ccd4a63SDavid du Colombier static Point curpos;
308ccd4a63SDavid du Colombier static int h;
318ccd4a63SDavid du Colombier static void	termscreenputs(char*, int);
328ccd4a63SDavid du Colombier 
338ccd4a63SDavid du Colombier 
348ccd4a63SDavid du Colombier static void
screenflush(void)358ccd4a63SDavid du Colombier screenflush(void)
368ccd4a63SDavid du Colombier {
378ccd4a63SDavid du Colombier 	drawflushr(flushr);
388ccd4a63SDavid du Colombier 	flushr = Rect(10000, 10000, -10000, -10000);
398ccd4a63SDavid du Colombier }
408ccd4a63SDavid du Colombier 
418ccd4a63SDavid du Colombier static void
addflush(Rectangle r)428ccd4a63SDavid du Colombier addflush(Rectangle r)
438ccd4a63SDavid du Colombier {
448ccd4a63SDavid du Colombier 	if(flushr.min.x >= flushr.max.x)
458ccd4a63SDavid du Colombier 		flushr = r;
468ccd4a63SDavid du Colombier 	else
478ccd4a63SDavid du Colombier 		combinerect(&flushr, r);
488ccd4a63SDavid du Colombier }
498ccd4a63SDavid du Colombier 
508ccd4a63SDavid du Colombier static void
screenwin(void)518ccd4a63SDavid du Colombier screenwin(void)
528ccd4a63SDavid du Colombier {
538ccd4a63SDavid du Colombier 	Point p;
548ccd4a63SDavid du Colombier 	char *greet;
558ccd4a63SDavid du Colombier 	Memimage *grey;
568ccd4a63SDavid du Colombier 
578ccd4a63SDavid du Colombier 	drawqlock();
588ccd4a63SDavid du Colombier 	back = memwhite;
598ccd4a63SDavid du Colombier 	conscol = memblack;
608ccd4a63SDavid du Colombier 	memfillcolor(gscreen, 0x444488FF);
618ccd4a63SDavid du Colombier 
628ccd4a63SDavid du Colombier 	h = memdefont->height;
638ccd4a63SDavid du Colombier 
648ccd4a63SDavid du Colombier 	window.min = addpt(gscreen->r.min, Pt(20,20));
658ccd4a63SDavid du Colombier 	window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
668ccd4a63SDavid du Colombier 	window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
678ccd4a63SDavid du Colombier 
688ccd4a63SDavid du Colombier 	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
698ccd4a63SDavid du Colombier 	window = insetrect(window, 4);
708ccd4a63SDavid du Colombier 	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
718ccd4a63SDavid du Colombier 
728ccd4a63SDavid du Colombier 	/* a lot of work to get a grey color */
738ccd4a63SDavid du Colombier 	grey = allocmemimage(Rect(0,0,1,1), CMAP8);
748ccd4a63SDavid du Colombier 	grey->flags |= Frepl;
758ccd4a63SDavid du Colombier 	grey->clipr = gscreen->r;
768ccd4a63SDavid du Colombier 	memfillcolor(grey, 0xAAAAAAFF);
778ccd4a63SDavid du Colombier 	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
788ccd4a63SDavid du Colombier 			window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
798ccd4a63SDavid du Colombier 	freememimage(grey);
808ccd4a63SDavid du Colombier 	window = insetrect(window, 5);
818ccd4a63SDavid du Colombier 
828ccd4a63SDavid du Colombier 	greet = " Plan 9 Console ";
838ccd4a63SDavid du Colombier 	p = addpt(window.min, Pt(10, 0));
848ccd4a63SDavid du Colombier 	memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
858ccd4a63SDavid du Colombier 	window.min.y += h+6;
868ccd4a63SDavid du Colombier 	curpos = window.min;
878ccd4a63SDavid du Colombier 	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
888ccd4a63SDavid du Colombier 	flushmemscreen(gscreen->r);
898ccd4a63SDavid du Colombier 	drawqunlock();
908ccd4a63SDavid du Colombier }
918ccd4a63SDavid du Colombier 
928ccd4a63SDavid du Colombier void
terminit(void)938ccd4a63SDavid du Colombier terminit(void)
948ccd4a63SDavid du Colombier {
958ccd4a63SDavid du Colombier 	memdefont = getmemdefont();
968ccd4a63SDavid du Colombier 	out.pos.x = MINX;
978ccd4a63SDavid du Colombier 	out.pos.y = 0;
988ccd4a63SDavid du Colombier 	out.bwid = memdefont->info[' '].width;
998ccd4a63SDavid du Colombier 	screenwin();
1008ccd4a63SDavid du Colombier 	screenputs = termscreenputs;
1018ccd4a63SDavid du Colombier }
1028ccd4a63SDavid du Colombier 
1038ccd4a63SDavid du Colombier static void
scroll(void)1048ccd4a63SDavid du Colombier scroll(void)
1058ccd4a63SDavid du Colombier {
1068ccd4a63SDavid du Colombier 	int o;
1078ccd4a63SDavid du Colombier 	Point p;
1088ccd4a63SDavid du Colombier 	Rectangle r;
1098ccd4a63SDavid du Colombier 
1108ccd4a63SDavid du Colombier 	o = 8*h;
1118ccd4a63SDavid du Colombier 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
1128ccd4a63SDavid du Colombier 	p = Pt(window.min.x, window.min.y+o);
1138ccd4a63SDavid du Colombier 	memimagedraw(gscreen, r, gscreen, p, nil, p, S);
1148ccd4a63SDavid du Colombier 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
1158ccd4a63SDavid du Colombier 	memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
1168ccd4a63SDavid du Colombier 	flushmemscreen(gscreen->r);
1178ccd4a63SDavid du Colombier 	curpos.y -= o;
1188ccd4a63SDavid du Colombier }
1198ccd4a63SDavid du Colombier 
1208ccd4a63SDavid du Colombier static void
screenputc(char * buf)1218ccd4a63SDavid du Colombier screenputc(char *buf)
1228ccd4a63SDavid du Colombier {
1238ccd4a63SDavid du Colombier 	Point p;
1248ccd4a63SDavid du Colombier 	int w, pos;
1258ccd4a63SDavid du Colombier 	Rectangle r;
1268ccd4a63SDavid du Colombier 	static int *xp;
1278ccd4a63SDavid du Colombier 	static int xbuf[256];
1288ccd4a63SDavid du Colombier 
129*391922e8SDavid du Colombier 	if(xp < xbuf || xp >= &xbuf[nelem(xbuf)])
1308ccd4a63SDavid du Colombier 		xp = xbuf;
1318ccd4a63SDavid du Colombier 
1328ccd4a63SDavid du Colombier 	switch(buf[0]) {
1338ccd4a63SDavid du Colombier 	case '\n':
1348ccd4a63SDavid du Colombier 		if(curpos.y+h >= window.max.y)
1358ccd4a63SDavid du Colombier 			scroll();
1368ccd4a63SDavid du Colombier 		curpos.y += h;
1378ccd4a63SDavid du Colombier 		screenputc("\r");
1388ccd4a63SDavid du Colombier 		break;
1398ccd4a63SDavid du Colombier 	case '\r':
1408ccd4a63SDavid du Colombier 		xp = xbuf;
1418ccd4a63SDavid du Colombier 		curpos.x = window.min.x;
1428ccd4a63SDavid du Colombier 		break;
1438ccd4a63SDavid du Colombier 	case '\t':
1448ccd4a63SDavid du Colombier 		p = memsubfontwidth(memdefont, " ");
1458ccd4a63SDavid du Colombier 		w = p.x;
1468ccd4a63SDavid du Colombier 		*xp++ = curpos.x;
1478ccd4a63SDavid du Colombier 		pos = (curpos.x-window.min.x)/w;
1488ccd4a63SDavid du Colombier 		pos = 8-(pos%8);
1498ccd4a63SDavid du Colombier 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
1508ccd4a63SDavid du Colombier 		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
1518ccd4a63SDavid du Colombier 		addflush(r);
1528ccd4a63SDavid du Colombier 		curpos.x += pos*w;
1538ccd4a63SDavid du Colombier 		break;
1548ccd4a63SDavid du Colombier 	case '\b':
1558ccd4a63SDavid du Colombier 		if(xp <= xbuf)
1568ccd4a63SDavid du Colombier 			break;
1578ccd4a63SDavid du Colombier 		xp--;
1588ccd4a63SDavid du Colombier 		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
1598ccd4a63SDavid du Colombier 		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
1608ccd4a63SDavid du Colombier 		addflush(r);
1618ccd4a63SDavid du Colombier 		curpos.x = *xp;
1628ccd4a63SDavid du Colombier 		break;
1638ccd4a63SDavid du Colombier 	default:
1648ccd4a63SDavid du Colombier 		p = memsubfontwidth(memdefont, buf);
1658ccd4a63SDavid du Colombier 		w = p.x;
1668ccd4a63SDavid du Colombier 
1678ccd4a63SDavid du Colombier 		if(curpos.x >= window.max.x-w)
1688ccd4a63SDavid du Colombier 			screenputc("\n");
1698ccd4a63SDavid du Colombier 
1708ccd4a63SDavid du Colombier 		*xp++ = curpos.x;
1718ccd4a63SDavid du Colombier 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
1728ccd4a63SDavid du Colombier 		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
1738ccd4a63SDavid du Colombier 		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
1748ccd4a63SDavid du Colombier 		addflush(r);
1758ccd4a63SDavid du Colombier 		curpos.x += w;
1768ccd4a63SDavid du Colombier 	}
1778ccd4a63SDavid du Colombier }
1788ccd4a63SDavid du Colombier 
1798ccd4a63SDavid du Colombier static void
termscreenputs(char * s,int n)1808ccd4a63SDavid du Colombier termscreenputs(char *s, int n)
1818ccd4a63SDavid du Colombier {
1828ccd4a63SDavid du Colombier 	int i, locked;
1838ccd4a63SDavid du Colombier 	Rune r;
1848ccd4a63SDavid du Colombier 	char buf[4];
1858ccd4a63SDavid du Colombier 
1868ccd4a63SDavid du Colombier 	lock(&screenlock);
1878ccd4a63SDavid du Colombier 	locked = drawcanqlock();
1888ccd4a63SDavid du Colombier 	while(n > 0){
1898ccd4a63SDavid du Colombier 		i = chartorune(&r, s);
1908ccd4a63SDavid du Colombier 		if(i == 0){
1918ccd4a63SDavid du Colombier 			s++;
1928ccd4a63SDavid du Colombier 			--n;
1938ccd4a63SDavid du Colombier 			continue;
1948ccd4a63SDavid du Colombier 		}
1958ccd4a63SDavid du Colombier 		memmove(buf, s, i);
1968ccd4a63SDavid du Colombier 		buf[i] = 0;
1978ccd4a63SDavid du Colombier 		n -= i;
1988ccd4a63SDavid du Colombier 		s += i;
1998ccd4a63SDavid du Colombier 		screenputc(buf);
2008ccd4a63SDavid du Colombier 	}
2018ccd4a63SDavid du Colombier 	if(locked)
2028ccd4a63SDavid du Colombier 		drawqunlock();
2038ccd4a63SDavid du Colombier 	screenflush();
2048ccd4a63SDavid du Colombier 	unlock(&screenlock);
2058ccd4a63SDavid du Colombier }
206