xref: /plan9/sys/src/cmd/unix/drawterm/kern/term.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include	"u.h"
2*8ccd4a63SDavid du Colombier #include	"lib.h"
3*8ccd4a63SDavid du Colombier #include	"dat.h"
4*8ccd4a63SDavid du Colombier #include	"fns.h"
5*8ccd4a63SDavid du Colombier #include	"error.h"
6*8ccd4a63SDavid du Colombier 
7*8ccd4a63SDavid du Colombier #include	<draw.h>
8*8ccd4a63SDavid du Colombier #include	<memdraw.h>
9*8ccd4a63SDavid du Colombier #include	"screen.h"
10*8ccd4a63SDavid du Colombier 
11*8ccd4a63SDavid du Colombier #define	MINX	8
12*8ccd4a63SDavid du Colombier #define	Backgnd		0xFF	/* white */
13*8ccd4a63SDavid du Colombier 
14*8ccd4a63SDavid du Colombier 		Memsubfont	*memdefont;
15*8ccd4a63SDavid du Colombier 
16*8ccd4a63SDavid du Colombier struct{
17*8ccd4a63SDavid du Colombier 	Point	pos;
18*8ccd4a63SDavid du Colombier 	int	bwid;
19*8ccd4a63SDavid du Colombier }out;
20*8ccd4a63SDavid du Colombier 
21*8ccd4a63SDavid du Colombier Lock	screenlock;
22*8ccd4a63SDavid du Colombier 
23*8ccd4a63SDavid du Colombier Memimage *conscol;
24*8ccd4a63SDavid du Colombier Memimage *back;
25*8ccd4a63SDavid du Colombier extern Memimage *gscreen;
26*8ccd4a63SDavid du Colombier 
27*8ccd4a63SDavid du Colombier static Rectangle flushr;
28*8ccd4a63SDavid du Colombier static Rectangle window;
29*8ccd4a63SDavid du Colombier static Point curpos;
30*8ccd4a63SDavid du Colombier static int h;
31*8ccd4a63SDavid du Colombier static void	termscreenputs(char*, int);
32*8ccd4a63SDavid du Colombier 
33*8ccd4a63SDavid du Colombier 
34*8ccd4a63SDavid du Colombier static void
screenflush(void)35*8ccd4a63SDavid du Colombier screenflush(void)
36*8ccd4a63SDavid du Colombier {
37*8ccd4a63SDavid du Colombier 	drawflushr(flushr);
38*8ccd4a63SDavid du Colombier 	flushr = Rect(10000, 10000, -10000, -10000);
39*8ccd4a63SDavid du Colombier }
40*8ccd4a63SDavid du Colombier 
41*8ccd4a63SDavid du Colombier static void
addflush(Rectangle r)42*8ccd4a63SDavid du Colombier addflush(Rectangle r)
43*8ccd4a63SDavid du Colombier {
44*8ccd4a63SDavid du Colombier 	if(flushr.min.x >= flushr.max.x)
45*8ccd4a63SDavid du Colombier 		flushr = r;
46*8ccd4a63SDavid du Colombier 	else
47*8ccd4a63SDavid du Colombier 		combinerect(&flushr, r);
48*8ccd4a63SDavid du Colombier }
49*8ccd4a63SDavid du Colombier 
50*8ccd4a63SDavid du Colombier static void
screenwin(void)51*8ccd4a63SDavid du Colombier screenwin(void)
52*8ccd4a63SDavid du Colombier {
53*8ccd4a63SDavid du Colombier 	Point p;
54*8ccd4a63SDavid du Colombier 	char *greet;
55*8ccd4a63SDavid du Colombier 	Memimage *grey;
56*8ccd4a63SDavid du Colombier 
57*8ccd4a63SDavid du Colombier 	drawqlock();
58*8ccd4a63SDavid du Colombier 	back = memwhite;
59*8ccd4a63SDavid du Colombier 	conscol = memblack;
60*8ccd4a63SDavid du Colombier 	memfillcolor(gscreen, 0x444488FF);
61*8ccd4a63SDavid du Colombier 
62*8ccd4a63SDavid du Colombier 	h = memdefont->height;
63*8ccd4a63SDavid du Colombier 
64*8ccd4a63SDavid du Colombier 	window.min = addpt(gscreen->r.min, Pt(20,20));
65*8ccd4a63SDavid du Colombier 	window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
66*8ccd4a63SDavid du Colombier 	window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
67*8ccd4a63SDavid du Colombier 
68*8ccd4a63SDavid du Colombier 	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
69*8ccd4a63SDavid du Colombier 	window = insetrect(window, 4);
70*8ccd4a63SDavid du Colombier 	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
71*8ccd4a63SDavid du Colombier 
72*8ccd4a63SDavid du Colombier 	/* a lot of work to get a grey color */
73*8ccd4a63SDavid du Colombier 	grey = allocmemimage(Rect(0,0,1,1), CMAP8);
74*8ccd4a63SDavid du Colombier 	grey->flags |= Frepl;
75*8ccd4a63SDavid du Colombier 	grey->clipr = gscreen->r;
76*8ccd4a63SDavid du Colombier 	memfillcolor(grey, 0xAAAAAAFF);
77*8ccd4a63SDavid du Colombier 	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
78*8ccd4a63SDavid du Colombier 			window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
79*8ccd4a63SDavid du Colombier 	freememimage(grey);
80*8ccd4a63SDavid du Colombier 	window = insetrect(window, 5);
81*8ccd4a63SDavid du Colombier 
82*8ccd4a63SDavid du Colombier 	greet = " Plan 9 Console ";
83*8ccd4a63SDavid du Colombier 	p = addpt(window.min, Pt(10, 0));
84*8ccd4a63SDavid du Colombier 	memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
85*8ccd4a63SDavid du Colombier 	window.min.y += h+6;
86*8ccd4a63SDavid du Colombier 	curpos = window.min;
87*8ccd4a63SDavid du Colombier 	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
88*8ccd4a63SDavid du Colombier 	flushmemscreen(gscreen->r);
89*8ccd4a63SDavid du Colombier 	drawqunlock();
90*8ccd4a63SDavid du Colombier }
91*8ccd4a63SDavid du Colombier 
92*8ccd4a63SDavid du Colombier void
terminit(void)93*8ccd4a63SDavid du Colombier terminit(void)
94*8ccd4a63SDavid du Colombier {
95*8ccd4a63SDavid du Colombier 	memdefont = getmemdefont();
96*8ccd4a63SDavid du Colombier 	out.pos.x = MINX;
97*8ccd4a63SDavid du Colombier 	out.pos.y = 0;
98*8ccd4a63SDavid du Colombier 	out.bwid = memdefont->info[' '].width;
99*8ccd4a63SDavid du Colombier 	screenwin();
100*8ccd4a63SDavid du Colombier 	screenputs = termscreenputs;
101*8ccd4a63SDavid du Colombier }
102*8ccd4a63SDavid du Colombier 
103*8ccd4a63SDavid du Colombier static void
scroll(void)104*8ccd4a63SDavid du Colombier scroll(void)
105*8ccd4a63SDavid du Colombier {
106*8ccd4a63SDavid du Colombier 	int o;
107*8ccd4a63SDavid du Colombier 	Point p;
108*8ccd4a63SDavid du Colombier 	Rectangle r;
109*8ccd4a63SDavid du Colombier 
110*8ccd4a63SDavid du Colombier 	o = 8*h;
111*8ccd4a63SDavid du Colombier 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
112*8ccd4a63SDavid du Colombier 	p = Pt(window.min.x, window.min.y+o);
113*8ccd4a63SDavid du Colombier 	memimagedraw(gscreen, r, gscreen, p, nil, p, S);
114*8ccd4a63SDavid du Colombier 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
115*8ccd4a63SDavid du Colombier 	memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
116*8ccd4a63SDavid du Colombier 	flushmemscreen(gscreen->r);
117*8ccd4a63SDavid du Colombier 	curpos.y -= o;
118*8ccd4a63SDavid du Colombier }
119*8ccd4a63SDavid du Colombier 
120*8ccd4a63SDavid du Colombier static void
screenputc(char * buf)121*8ccd4a63SDavid du Colombier screenputc(char *buf)
122*8ccd4a63SDavid du Colombier {
123*8ccd4a63SDavid du Colombier 	Point p;
124*8ccd4a63SDavid du Colombier 	int w, pos;
125*8ccd4a63SDavid du Colombier 	Rectangle r;
126*8ccd4a63SDavid du Colombier 	static int *xp;
127*8ccd4a63SDavid du Colombier 	static int xbuf[256];
128*8ccd4a63SDavid du Colombier 
129*8ccd4a63SDavid du Colombier 	if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
130*8ccd4a63SDavid du Colombier 		xp = xbuf;
131*8ccd4a63SDavid du Colombier 
132*8ccd4a63SDavid du Colombier 	switch(buf[0]) {
133*8ccd4a63SDavid du Colombier 	case '\n':
134*8ccd4a63SDavid du Colombier 		if(curpos.y+h >= window.max.y)
135*8ccd4a63SDavid du Colombier 			scroll();
136*8ccd4a63SDavid du Colombier 		curpos.y += h;
137*8ccd4a63SDavid du Colombier 		screenputc("\r");
138*8ccd4a63SDavid du Colombier 		break;
139*8ccd4a63SDavid du Colombier 	case '\r':
140*8ccd4a63SDavid du Colombier 		xp = xbuf;
141*8ccd4a63SDavid du Colombier 		curpos.x = window.min.x;
142*8ccd4a63SDavid du Colombier 		break;
143*8ccd4a63SDavid du Colombier 	case '\t':
144*8ccd4a63SDavid du Colombier 		p = memsubfontwidth(memdefont, " ");
145*8ccd4a63SDavid du Colombier 		w = p.x;
146*8ccd4a63SDavid du Colombier 		*xp++ = curpos.x;
147*8ccd4a63SDavid du Colombier 		pos = (curpos.x-window.min.x)/w;
148*8ccd4a63SDavid du Colombier 		pos = 8-(pos%8);
149*8ccd4a63SDavid du Colombier 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
150*8ccd4a63SDavid du Colombier 		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
151*8ccd4a63SDavid du Colombier 		addflush(r);
152*8ccd4a63SDavid du Colombier 		curpos.x += pos*w;
153*8ccd4a63SDavid du Colombier 		break;
154*8ccd4a63SDavid du Colombier 	case '\b':
155*8ccd4a63SDavid du Colombier 		if(xp <= xbuf)
156*8ccd4a63SDavid du Colombier 			break;
157*8ccd4a63SDavid du Colombier 		xp--;
158*8ccd4a63SDavid du Colombier 		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
159*8ccd4a63SDavid du Colombier 		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
160*8ccd4a63SDavid du Colombier 		addflush(r);
161*8ccd4a63SDavid du Colombier 		curpos.x = *xp;
162*8ccd4a63SDavid du Colombier 		break;
163*8ccd4a63SDavid du Colombier 	default:
164*8ccd4a63SDavid du Colombier 		p = memsubfontwidth(memdefont, buf);
165*8ccd4a63SDavid du Colombier 		w = p.x;
166*8ccd4a63SDavid du Colombier 
167*8ccd4a63SDavid du Colombier 		if(curpos.x >= window.max.x-w)
168*8ccd4a63SDavid du Colombier 			screenputc("\n");
169*8ccd4a63SDavid du Colombier 
170*8ccd4a63SDavid du Colombier 		*xp++ = curpos.x;
171*8ccd4a63SDavid du Colombier 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
172*8ccd4a63SDavid du Colombier 		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
173*8ccd4a63SDavid du Colombier 		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
174*8ccd4a63SDavid du Colombier 		addflush(r);
175*8ccd4a63SDavid du Colombier 		curpos.x += w;
176*8ccd4a63SDavid du Colombier 	}
177*8ccd4a63SDavid du Colombier }
178*8ccd4a63SDavid du Colombier 
179*8ccd4a63SDavid du Colombier static void
termscreenputs(char * s,int n)180*8ccd4a63SDavid du Colombier termscreenputs(char *s, int n)
181*8ccd4a63SDavid du Colombier {
182*8ccd4a63SDavid du Colombier 	int i, locked;
183*8ccd4a63SDavid du Colombier 	Rune r;
184*8ccd4a63SDavid du Colombier 	char buf[4];
185*8ccd4a63SDavid du Colombier 
186*8ccd4a63SDavid du Colombier 	lock(&screenlock);
187*8ccd4a63SDavid du Colombier 	locked = drawcanqlock();
188*8ccd4a63SDavid du Colombier 	while(n > 0){
189*8ccd4a63SDavid du Colombier 		i = chartorune(&r, s);
190*8ccd4a63SDavid du Colombier 		if(i == 0){
191*8ccd4a63SDavid du Colombier 			s++;
192*8ccd4a63SDavid du Colombier 			--n;
193*8ccd4a63SDavid du Colombier 			continue;
194*8ccd4a63SDavid du Colombier 		}
195*8ccd4a63SDavid du Colombier 		memmove(buf, s, i);
196*8ccd4a63SDavid du Colombier 		buf[i] = 0;
197*8ccd4a63SDavid du Colombier 		n -= i;
198*8ccd4a63SDavid du Colombier 		s += i;
199*8ccd4a63SDavid du Colombier 		screenputc(buf);
200*8ccd4a63SDavid du Colombier 	}
201*8ccd4a63SDavid du Colombier 	if(locked)
202*8ccd4a63SDavid du Colombier 		drawqunlock();
203*8ccd4a63SDavid du Colombier 	screenflush();
204*8ccd4a63SDavid du Colombier 	unlock(&screenlock);
205*8ccd4a63SDavid du Colombier }
206