Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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