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	<libc.h>
3
#include	"compat.h"
4
#include	"kbd.h"
5
#include	"error.h"
6
 
7
#define	Image	IMAGE
8
#include	<draw.h>
9
#include	<memdraw.h>
10
#include	<cursor.h>
11
#include	"screen.h"
12
 
13
enum
14
{
15
	CURSORDIM = 16
16
};
17
 
18
Memimage	*gscreen;
19
Point		ZP;
20
int		cursorver;
21
Point		cursorpos;
22
 
23
static Memimage		*back;
24
static Memimage		*conscol;
25
static Memimage		*curscol;
26
static Point		curpos;
27
static Memsubfont	*memdefont;
28
static Rectangle	flushr;
29
static Rectangle	window;
30
static int		h;
31
static int		w;
32
 
33
static Rectangle	cursorr;
34
static Point		offscreen;
35
static uchar		cursset[CURSORDIM*CURSORDIM/8];
36
static uchar		cursclr[CURSORDIM*CURSORDIM/8];
37
static int		cursdrawvers = -1;
38
static Memimage		*cursorset;
39
static Memimage		*cursorclear;
40
static Cursor		screencursor;
41
 
42
Cursor	arrow = {
43
	{ -1, -1 },
44
	{ 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
45
	  0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
46
	  0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
47
	  0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
48
	},
49
	{ 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
50
	  0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
51
	  0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
52
	  0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
53
	},
54
};
55
 
56
void
57
screeninit(int x, int y, char *chanstr)
58
{
59
	Point p, q;
60
	char *greet;
61
	char buf[128];
62
	Memimage *grey;
63
	Rectangle r;
64
	int chan;
65
 
66
	cursorver = 0;
67
 
68
	memimageinit();
69
	chan = strtochan(chanstr);
70
	if(chan == 0)
71
		error("bad screen channel string");
72
 
73
	r = Rect(0, 0, x, y);
74
	gscreen = allocmemimage(r, chan);
75
	if(gscreen == nil){
76
		snprint(buf, sizeof buf, "can't allocate screen image: %r");
77
		error(buf);
78
	}
79
 
80
	offscreen = Pt(x + 100, y + 100);
81
	cursorr = Rect(0, 0, CURSORDIM, CURSORDIM);
82
	cursorset = allocmemimage(cursorr, GREY8);
83
	cursorclear = allocmemimage(cursorr, GREY1);
84
	if(cursorset == nil || cursorclear == nil){
85
		freememimage(gscreen);
86
		freememimage(cursorset);
87
		freememimage(cursorclear);
88
		gscreen = nil;
89
		cursorset = nil;
90
		cursorclear = nil;
91
		snprint(buf, sizeof buf, "can't allocate cursor images: %r");
92
		error(buf);
93
	}
94
 
95
	drawlock();
96
 
97
	/*
98
	 * set up goo for screenputs
99
	 */
100
	memdefont = getmemdefont();
101
 
102
	back = memwhite;
103
	conscol = memblack;
104
 
105
	/* a lot of work to get a grey color */
106
	curscol = allocmemimage(Rect(0,0,1,1), RGBA32);
107
	curscol->flags |= Frepl;
108
	curscol->clipr = gscreen->r;
109
	memfillcolor(curscol, 0xff0000ff);
110
 
111
	memfillcolor(gscreen, 0x444488FF);
112
 
113
	w = memdefont->info[' '].width;
114
	h = memdefont->height;
115
 
116
	window.min = addpt(gscreen->r.min, Pt(20,20));
117
	window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
118
	window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
119
 
120
	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
121
	window = insetrect(window, 4);
122
	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
123
 
124
	/* a lot of work to get a grey color */
125
	grey = allocmemimage(Rect(0,0,1,1), CMAP8);
126
	grey->flags |= Frepl;
127
	grey->clipr = gscreen->r;
128
	memfillcolor(grey, 0xAAAAAAFF);
129
	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
130
			window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
131
	freememimage(grey);
132
	window = insetrect(window, 5);
133
 
134
	greet = " Plan 9 Console ";
135
	p = addpt(window.min, Pt(10, 0));
136
	q = memsubfontwidth(memdefont, greet);
137
	memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
138
	window.min.y += h+6;
139
	curpos = window.min;
140
	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
141
	flushmemscreen(gscreen->r);
142
 
143
	drawunlock();
144
 
145
	setcursor(&arrow);
146
}
147
 
148
uchar*
149
attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
150
{
151
	*r = gscreen->r;
152
	*d = gscreen->depth;
153
	*chan = gscreen->chan;
154
	*width = gscreen->width;
155
	*softscreen = 1;
156
 
157
	return gscreen->data->bdata;
158
}
159
 
160
void
161
getcolor(ulong , ulong* pr, ulong* pg, ulong* pb)
162
{
163
	*pr = 0;
164
	*pg = 0;
165
	*pb = 0;
166
}
167
 
168
int
169
setcolor(ulong , ulong , ulong , ulong )
170
{
171
	return 0;
172
}
173
 
174
/*
175
 * called with cursor unlocked, drawlock locked
176
 */
177
void
178
cursordraw(Memimage *dst, Rectangle r)
179
{
180
	static uchar set[CURSORDIM*CURSORDIM], clr[CURSORDIM*CURSORDIM/8];
181
	static int ver = -1;
182
	int i, j, n;
183
 
184
	lock(&cursor);
185
	if(ver != cursorver){
186
		n = 0;
187
		for(i = 0; i < CURSORDIM*CURSORDIM/8; i += CURSORDIM/8){
188
			for(j = 0; j < CURSORDIM; j++){
189
				if(cursset[i + (j >> 3)] & (1 << (7 - (j & 7))))
190
					set[n] = 0xaa;
191
				else
192
					set[n] = 0;
193
				n++;
194
			}
195
		}
196
		memmove(clr, cursclr, CURSORDIM*CURSORDIM/8);
197
		ver = cursorver;
198
		unlock(&cursor);
199
		loadmemimage(cursorset, cursorr, set, CURSORDIM*CURSORDIM);
200
		loadmemimage(cursorclear, cursorr, clr, CURSORDIM*CURSORDIM/8);
201
	}else
202
		unlock(&cursor);
203
	memimagedraw(dst, r, memwhite, ZP, cursorclear, ZP, SoverD);
204
	memimagedraw(dst, r, curscol, ZP, cursorset, ZP, SoverD);
205
}
206
 
207
/*
208
 * called with cursor locked, drawlock possibly unlocked
209
 */
210
Rectangle
211
cursorrect(void)
212
{
213
	Rectangle r;
214
 
215
	r.min.x = cursorpos.x + cursor.offset.x;
216
	r.min.y = cursorpos.y + cursor.offset.y;
217
	r.max.x = r.min.x + CURSORDIM;
218
	r.max.y = r.min.y + CURSORDIM;
219
	return r;
220
}
221
 
222
/*
223
 * called with cursor locked, drawlock possibly unlocked
224
 */
225
void
226
setcursor(Cursor* curs)
227
{
228
	cursorver++;
229
	memmove(cursset, curs->set, CURSORDIM*CURSORDIM/8);
230
	memmove(cursclr, curs->clr, CURSORDIM*CURSORDIM/8);
231
}
232
 
233
int
234
cursoron(int dolock)
235
{
236
	if(dolock)
237
		lock(&cursor);
238
	cursorpos = mousexy();
239
	if(dolock)
240
		unlock(&cursor);
241
 
242
	return 0;
243
}
244
 
245
void
246
cursoroff(int dolock)
247
{
248
	if(dolock)
249
		lock(&cursor);
250
	cursorpos = offscreen;
251
	if(dolock)
252
		unlock(&cursor);
253
}
254
 
255
void
256
blankscreen(int blank)
257
{
258
	USED(blank);
259
}
260
 
261
static void
262
screenflush(void)
263
{
264
	flushmemscreen(flushr);
265
	flushr = Rect(10000, 10000, -10000, -10000);
266
}
267
 
268
static void
269
addflush(Rectangle r)
270
{
271
	if(flushr.min.x >= flushr.max.x)
272
		flushr = r;
273
	else
274
		combinerect(&flushr, r);
275
}
276
 
277
static void
278
scroll(void)
279
{
280
	int o;
281
	Point p;
282
	Rectangle r;
283
 
284
	o = 8*h;
285
	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
286
	p = Pt(window.min.x, window.min.y+o);
287
	memimagedraw(gscreen, r, gscreen, p, nil, p, S);
288
	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
289
	memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
290
	flushmemscreen(gscreen->r);
291
 
292
	curpos.y -= o;
293
}
294
 
295
static void
296
screenputc(char *buf)
297
{
298
	Point p;
299
	int w, pos;
300
	Rectangle r;
301
	static int *xp;
302
	static int xbuf[256];
303
 
304
	if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
305
		xp = xbuf;
306
 
307
	switch(buf[0]){
308
	case '\n':
309
		if(curpos.y+h >= window.max.y)
310
			scroll();
311
		curpos.y += h;
312
		screenputc("\r");
313
		break;
314
	case '\r':
315
		xp = xbuf;
316
		curpos.x = window.min.x;
317
		break;
318
	case '\t':
319
		p = memsubfontwidth(memdefont, " ");
320
		w = p.x;
321
		*xp++ = curpos.x;
322
		pos = (curpos.x-window.min.x)/w;
323
		pos = 8-(pos%8);
324
		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
325
		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
326
		addflush(r);
327
		curpos.x += pos*w;
328
		break;
329
	case '\b':
330
		if(xp <= xbuf)
331
			break;
332
		xp--;
333
		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
334
		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
335
		addflush(r);
336
		curpos.x = *xp;
337
		break;
338
	default:
339
		p = memsubfontwidth(memdefont, buf);
340
		w = p.x;
341
 
342
		if(curpos.x >= window.max.x-w)
343
			screenputc("\n");
344
 
345
		*xp++ = curpos.x;
346
		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
347
		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
348
		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
349
		addflush(r);
350
		curpos.x += w;
351
	}
352
}
353
 
354
void
355
screenputs(char *s, int n)
356
{
357
	int i;
358
	Rune r;
359
	char buf[4];
360
 
361
	drawlock();
362
	while(n > 0){
363
		i = chartorune(&r, s);
364
		if(i == 0){
365
			s++;
366
			--n;
367
			continue;
368
		}
369
		memmove(buf, s, i);
370
		buf[i] = 0;
371
		n -= i;
372
		s += i;
373
		screenputc(buf);
374
	}
375
	screenflush();
376
	drawunlock();
377
}