plan 9 kernel history: overview | file list | diff list

1992/0622/port/devbit.c (diff list | history)

1992/0621/sys/src/9/port/devbit.c:37,441992/0622/sys/src/9/port/devbit.c:37,45 (short | long | prev | next)
1990/0329    
 */ 
 
/* 
1990/0327    
 * Arena is a word containing N, followed by a pointer to its bitmap, 
1992/0621    
 * followed by N blocks.  The bitmap pointer is zero if block is free. 
1992/0622    
 * Arena is a word containing N, followed by a pointer to the Arena, 
 * followed by a pointer to the Bitmap, followed by N words. 
 * The bitmap pointer is zero if block is free. 
1992/0621    
 * bit.map is an array of pointers to GBitmaps.  The GBitmaps are 
 * freed individually and their corresponding entries in bit.map are zeroed. 
 * The index into bit.map is the Bitmap id as seen in libg.  Subfonts and 
1992/0621/sys/src/9/port/devbit.c:45,621992/0622/sys/src/9/port/devbit.c:46,72
1992/0621    
 * fonts are handled similarly. 
1990/0327    
 */ 
1990/0324    
 
1992/0622    
typedef struct	Arena	Arena; 
struct Arena 
{ 
	ulong	*words;		/* storage */ 
	ulong	*wfree;		/* pointer to next free word */ 
	ulong	nwords;		/* total in arena */ 
	int	nbusy;		/* number of busy blocks */ 
}; 
 
1990/05313    
struct 
{ 
1990/0324    
	Ref; 
1992/0622    
	QLock; 
1992/0621    
	GBitmap	**map;		/* indexed array */ 
	int	nmap;		/* number allocated */ 
1990/0327    
	ulong	*words;		/* storage */ 
	ulong	nwords;		/* total in arena */ 
	ulong	*wfree;		/* pointer to next free word */ 
1992/0621    
	GFont	**font;		/* indexed array */ 
	int	nfont;		/* number allocated */ 
	GSubfont**subfont;	/* indexed array */ 
	int	nsubfont;	/* number allocated */ 
1992/0622    
	Arena	*arena;		/* array */ 
	int	narena;		/* number allocated */ 
1990/0327    
	int	lastid;		/* last allocated bitmap id */ 
1992/0209    
	int	lastsubfid;	/* last allocated subfont id */ 
1990/0623    
	int	lastfid;	/* last allocated font id */ 
1992/0621/sys/src/9/port/devbit.c:67,791992/0622/sys/src/9/port/devbit.c:77,91
1991/0706    
	int	mid;		/* colormap read bitmap id */ 
1990/0324    
}bit; 
 
1992/0621    
#define	DMAP	32		/* delta increase in size of arrays */ 
1992/0622    
#define	DMAP	16		/* delta increase in size of arrays */ 
1990/0327    
#define	FREE	0x80000000 
1992/0622    
 
1990/0327    
void	bitcompact(void); 
1992/0621    
int	bitalloc(Rectangle, int); 
1990/0902    
void	bitfree(GBitmap*); 
1992/0621    
void	fontfree(GFont*); 
void	subfontfree(GSubfont*); 
1992/0622    
void	arenafree(Arena*); 
1992/0209    
void	bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode); 
void	bitloadchar(GFont*, int, GSubfont*, int); 
1990/0912    
extern	GBitmap	gscreen; 
1992/0621/sys/src/9/port/devbit.c:149,1541992/0622/sys/src/9/port/devbit.c:161,167
1990/0324    
 
#define	NBIT	(sizeof bitdir/sizeof(Dirtab)) 
1992/0621    
#define	NINFO	8192 
1992/0622    
#define	HDR	3 
1990/0324    
 
void 
bitreset(void) 
1992/0621/sys/src/9/port/devbit.c:156,1611992/0622/sys/src/9/port/devbit.c:169,175
1990/0327    
	int i; 
1990/0902    
	GBitmap *bp; 
1991/0706    
	ulong r; 
1992/0622    
	Arena *a; 
1990/0327    
 
1992/0621    
	bit.map = smalloc(DMAP*sizeof(GBitmap*)); 
	bit.nmap = DMAP; 
1992/0621/sys/src/9/port/devbit.c:165,1781992/0622/sys/src/9/port/devbit.c:179,201
1990/0327    
	bit.lastid = -1; 
1992/0209    
	bit.lastsubfid = -1; 
1990/0623    
	bit.lastfid = -1; 
1990/0327    
	bit.words = ialloc(conf.nbitbyte, 0); 
1992/0621    
print("bitreset %lux\n", bit.words); 
1990/0327    
	bit.nwords = conf.nbitbyte/sizeof(ulong); 
	bit.wfree = bit.words; 
1992/0621    
	bit.font = smalloc(DMAP*sizeof(GFont*)); 
	bit.nfont = DMAP; 
	bit.subfont = smalloc(DMAP*sizeof(GSubfont*)); 
	bit.nsubfont = DMAP; 
1992/0622    
	bit.arena = smalloc(DMAP*sizeof(Arena)); 
	bit.narena = DMAP; 
	a = &bit.arena[0]; 
	/* 
	 * Somewhat of a heuristic: start with three screensful and 
	 * allocate single screensful dynamically if needed. 
	 */ 
	a->nwords = 3*(gscreen.width*gscreen.r.max.y+HDR); 
	a->words = xalloc(a->nwords*sizeof(ulong)); 
	if(a->words == 0) 
		panic("bitreset"); 
	a->wfree = a->words; 
	a->nbusy = 1;	/* keep 0th arena from being freed */ 
1990/05313    
	Cursortocursor(&arrow); 
1990/0324    
} 
 
1992/0621/sys/src/9/port/devbit.c:336,3431992/0622/sys/src/9/port/devbit.c:359,365
1990/11211    
	if(c->qid.path & CHDIR) 
1990/0324    
		return devdirread(c, va, n, bitdir, NBIT, devgen); 
 
1990/11211    
	switch(c->qid.path){ 
1990/0505    
	case Qmouse: 
1992/0622    
	if(c->qid.path == Qmouse){ 
1990/0329    
		/* 
1990/0505    
		 * mouse: 
		 *	'm'		1 
1992/0621/sys/src/9/port/devbit.c:361,5391992/0622/sys/src/9/port/devbit.c:383,391
1990/0505    
		PLONG(p+6, mouse.xy.y); 
		mouse.changed = 0; 
		unlock(&cursor); 
		n = 10; 
		break; 
                 
	case Qbitblt: 
		p = va; 
1990/0329    
		/* 
1990/0505    
		 * Fuss about and figure out what to say. 
1990/0329    
		 */ 
1990/0505    
		if(bit.init){ 
			/* 
			 * init: 
			 *	'I'		1 
			 *	ldepth		1 
			 * 	rectangle	16 
1990/06231    
			 * if count great enough, also 
			 *	font info	3*12 
			 *	fontchars	6*(defont->n+1) 
1990/0505    
			 */ 
			if(n < 18) 
1990/11211    
				error(Ebadblt); 
1990/0505    
			p[0] = 'I'; 
1990/0912    
			p[1] = gscreen.ldepth; 
			PLONG(p+2, gscreen.r.min.x); 
			PLONG(p+6, gscreen.r.min.y); 
			PLONG(p+10, gscreen.r.max.x); 
			PLONG(p+14, gscreen.r.max.y); 
1992/0605    
			dn = 18; 
			if(bit.init=='j' && n>=18+16){ 
				PLONG(p+18, gscreen.clipr.min.x); 
				PLONG(p+22, gscreen.clipr.min.y); 
				PLONG(p+26, gscreen.clipr.max.x); 
				PLONG(p+30, gscreen.clipr.max.y); 
				dn += 16; 
			} 
			if(n >= dn+3*12+6*(defont->n+1)){ 
				p += dn; 
1990/06231    
				sprint((char*)p, "%11d %11d %11d ", defont->n, 
					defont->height, defont->ascent); 
				p += 3*12; 
				for(i=defont->info,j=0; j<=defont->n; j++,i++,p+=6){ 
					PSHORT(p, i->x); 
					p[2] = i->top; 
					p[3] = i->bottom; 
					p[4] = i->left; 
					p[5] = i->width; 
				} 
1992/0605    
				n = dn+3*12+6*(defont->n+1); 
1990/06231    
			}else 
1992/0605    
				n = dn; 
1990/0505    
			bit.init = 0; 
			break; 
		} 
		if(bit.lastid > 0){ 
			/* 
			 * allocate: 
			 *	'A'		1 
			 *	bitmap id	2 
			 */ 
			if(n < 3) 
1990/11211    
				error(Ebadblt); 
1990/0505    
			p[0] = 'A'; 
			PSHORT(p+1, bit.lastid); 
			bit.lastid = -1; 
			n = 3; 
			break; 
		} 
1992/0209    
		if(bit.lastsubfid > 0){ 
1990/0623    
			/* 
1992/0209    
			 * allocate subfont: 
1990/0623    
			 *	'K'		1 
1992/0209    
			 *	subfont id	2 
1990/0623    
			 */ 
			if(n < 3) 
1990/11211    
				error(Ebadblt); 
1990/0623    
			p[0] = 'K'; 
1992/0209    
			PSHORT(p+1, bit.lastsubfid); 
			bit.lastsubfid = -1; 
			n = 3; 
			break; 
		} 
		if(bit.lastfid >= 0){ 
			/* 
			 * allocate font: 
			 *	'N'		1 
			 *	font id		2 
			 */ 
			if(n < 3) 
				error(Ebadblt); 
			p[0] = 'N'; 
1990/0623    
			PSHORT(p+1, bit.lastfid); 
			bit.lastfid = -1; 
			n = 3; 
			break; 
		} 
1991/0706    
		if(bit.mid >= 0){ 
			/* 
			 * read colormap: 
			 *	data		12*(2**bitmapdepth) 
			 */ 
1992/0621    
			src = bit.map[bit.mid]; 
			if(src == 0) 
				error(Ebadbitmap); 
			l = (1<<src->ldepth); 
1991/0706    
			nw = 1 << l; 
			if(n < 12*nw) 
				error(Ebadblt); 
			for(j = 0; j < nw; j++){ 
				if(bit.mid == 0){ 
					getcolor(flipping? ~j : j, &rv, &gv, &bv); 
				}else{ 
					rv = j; 
					for(off = 32-l; off > 0; off -= l) 
						rv = (rv << l) | j; 
					gv = bv = rv; 
				} 
				PLONG(p, rv); 
				PLONG(p+4, gv); 
				PLONG(p+8, bv); 
				p += 12; 
			} 
			bit.mid = -1; 
			n = 12*nw; 
			break; 
		} 
1990/0613    
		if(bit.rid >= 0){ 
			/* 
1991/0706    
			 * read bitmap: 
1990/0613    
			 *	data		bytewidth*(maxy-miny) 
			 */ 
1992/0621    
			src = bit.map[bit.rid]; 
			if(src == 0) 
1990/11211    
				error(Ebadbitmap); 
1990/0613    
			off = 0; 
			if(bit.rid == 0) 
				off = 1; 
			miny = bit.rminy; 
			maxy = bit.rmaxy; 
			if(miny>maxy || miny<src->r.min.y || maxy>src->r.max.y) 
1990/11211    
				error(Ebadblt); 
1990/0613    
			ws = 1<<(3-src->ldepth);	/* pixels per byte */ 
			/* set l to number of bytes of incoming data per scan line */ 
			if(src->r.min.x >= 0) 
				l = (src->r.max.x+ws-1)/ws - src->r.min.x/ws; 
			else{	/* make positive before divide */ 
				t = (-src->r.min.x)+ws-1; 
				t = (t/ws)*ws; 
				l = (t+src->r.max.x+ws-1)/ws; 
			} 
			if(n < l*(maxy-miny)) 
1990/11211    
				error(Ebadblt); 
1990/0613    
			if(off) 
				cursoroff(1); 
			n = 0; 
			p = va; 
			for(y=miny; y<maxy; y++){ 
1990/0912    
				q = (uchar*)gaddr(src, Pt(src->r.min.x, y)); 
1990/0911    
				q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws; 
1991/0706    
				if(bit.rid == 0 && flipping)	/* flip bits */ 
					for(x=0; x<l; x++) 
1992/0209    
						*p++ = ~(*q++); 
1991/0706    
				else 
					for(x=0; x<l; x++) 
1992/0209    
						*p++ = *q++; 
1990/0613    
				n += l; 
			} 
			if(off) 
				cursoron(1); 
			bit.rid = -1; 
			break; 
		} 
1990/11211    
		error(Ebadblt); 
1990/0709    
                 
	case Qscreen: 
1992/0622    
		return 10; 
	} 
	if(c->qid.path == Qscreen){ 
1991/0411    
		if(offset==0){ 
1990/0709    
			if(n < 5*12) 
1990/11211    
				error(Eio); 
1992/0621/sys/src/9/port/devbit.c:541,5481992/0622/sys/src/9/port/devbit.c:393,399
1990/0912    
				gscreen.ldepth, gscreen.r.min.x, 
				gscreen.r.min.y, gscreen.r.max.x, 
				gscreen.r.max.y); 
1990/0709    
			n = 5*12; 
			break; 
1992/0622    
			return 5*12; 
1990/0709    
		} 
1990/0912    
		ws = 1<<(3-gscreen.ldepth);	/* pixels per byte */ 
		l = (gscreen.r.max.x+ws-1)/ws - gscreen.r.min.x/ws; 
1992/0621/sys/src/9/port/devbit.c:565,5761992/0622/sys/src/9/port/devbit.c:416,589
1992/0209    
					*p++ = *q++; 
1990/0709    
			n += l; 
		} 
		break; 
1990/0505    
                 
	default: 
1992/0622    
		return n; 
	} 
	if(c->qid.path != Qbitblt) 
1990/11211    
		error(Egreg); 
1992/0622    
 
	qlock(&bit); 
	if(waserror()){ 
		qunlock(&bit); 
		nexterror(); 
1990/0327    
	} 
1992/0622    
	p = va; 
	/* 
	 * Fuss about and figure out what to say. 
	 */ 
	if(bit.init){ 
		/* 
		 * init: 
		 *	'I'		1 
		 *	ldepth		1 
		 * 	rectangle	16 
		 * if count great enough, also 
		 *	font info	3*12 
		 *	fontchars	6*(defont->n+1) 
		 */ 
		if(n < 18) 
			error(Ebadblt); 
		p[0] = 'I'; 
		p[1] = gscreen.ldepth; 
		PLONG(p+2, gscreen.r.min.x); 
		PLONG(p+6, gscreen.r.min.y); 
		PLONG(p+10, gscreen.r.max.x); 
		PLONG(p+14, gscreen.r.max.y); 
		dn = 18; 
		if(bit.init=='j' && n>=18+16){ 
			PLONG(p+18, gscreen.clipr.min.x); 
			PLONG(p+22, gscreen.clipr.min.y); 
			PLONG(p+26, gscreen.clipr.max.x); 
			PLONG(p+30, gscreen.clipr.max.y); 
			dn += 16; 
		} 
		if(n >= dn+3*12+6*(defont->n+1)){ 
			p += dn; 
			sprint((char*)p, "%11d %11d %11d ", defont->n, 
				defont->height, defont->ascent); 
			p += 3*12; 
			for(i=defont->info,j=0; j<=defont->n; j++,i++,p+=6){ 
				PSHORT(p, i->x); 
				p[2] = i->top; 
				p[3] = i->bottom; 
				p[4] = i->left; 
				p[5] = i->width; 
			} 
			n = dn+3*12+6*(defont->n+1); 
		}else 
			n = dn; 
		bit.init = 0; 
	}else if(bit.lastid > 0){ 
		/* 
		 * allocate: 
		 *	'A'		1 
		 *	bitmap id	2 
		 */ 
		if(n < 3) 
			error(Ebadblt); 
		p[0] = 'A'; 
		PSHORT(p+1, bit.lastid); 
		bit.lastid = -1; 
		n = 3; 
	}else if(bit.lastsubfid > 0){ 
		/* 
		 * allocate subfont: 
		 *	'K'		1 
		 *	subfont id	2 
		 */ 
		if(n < 3) 
			error(Ebadblt); 
		p[0] = 'K'; 
		PSHORT(p+1, bit.lastsubfid); 
		bit.lastsubfid = -1; 
		n = 3; 
	}else if(bit.lastfid >= 0){ 
		/* 
		 * allocate font: 
		 *	'N'		1 
		 *	font id		2 
		 */ 
		if(n < 3) 
			error(Ebadblt); 
		p[0] = 'N'; 
		PSHORT(p+1, bit.lastfid); 
		bit.lastfid = -1; 
		n = 3; 
	}else if(bit.mid >= 0){ 
		/* 
		 * read colormap: 
		 *	data		12*(2**bitmapdepth) 
		 */ 
		src = bit.map[bit.mid]; 
		if(src == 0) 
			error(Ebadbitmap); 
		l = (1<<src->ldepth); 
		nw = 1 << l; 
		if(n < 12*nw) 
			error(Ebadblt); 
		for(j = 0; j < nw; j++){ 
			if(bit.mid == 0){ 
				getcolor(flipping? ~j : j, &rv, &gv, &bv); 
			}else{ 
				rv = j; 
				for(off = 32-l; off > 0; off -= l) 
					rv = (rv << l) | j; 
				gv = bv = rv; 
			} 
			PLONG(p, rv); 
			PLONG(p+4, gv); 
			PLONG(p+8, bv); 
			p += 12; 
		} 
		bit.mid = -1; 
		n = 12*nw; 
	}else if(bit.rid >= 0){ 
		/* 
		 * read bitmap: 
		 *	data		bytewidth*(maxy-miny) 
		 */ 
		src = bit.map[bit.rid]; 
		if(src == 0) 
			error(Ebadbitmap); 
		off = 0; 
		if(bit.rid == 0) 
			off = 1; 
		miny = bit.rminy; 
		maxy = bit.rmaxy; 
		if(miny>maxy || miny<src->r.min.y || maxy>src->r.max.y) 
			error(Ebadblt); 
		ws = 1<<(3-src->ldepth);	/* pixels per byte */ 
		/* set l to number of bytes of incoming data per scan line */ 
		if(src->r.min.x >= 0) 
			l = (src->r.max.x+ws-1)/ws - src->r.min.x/ws; 
		else{	/* make positive before divide */ 
			t = (-src->r.min.x)+ws-1; 
			t = (t/ws)*ws; 
			l = (t+src->r.max.x+ws-1)/ws; 
		} 
		if(n < l*(maxy-miny)) 
			error(Ebadblt); 
		if(off) 
			cursoroff(1); 
		n = 0; 
		p = va; 
		for(y=miny; y<maxy; y++){ 
			q = (uchar*)gaddr(src, Pt(src->r.min.x, y)); 
			q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws; 
			if(bit.rid == 0 && flipping)	/* flip bits */ 
				for(x=0; x<l; x++) 
					*p++ = ~(*q++); 
			else 
				for(x=0; x<l; x++) 
					*p++ = *q++; 
			n += l; 
		} 
		if(off) 
			cursoron(1); 
		bit.rid = -1; 
	} 
1990/0327    
 
1992/0622    
	poperror(); 
	qunlock(&bit); 
1990/0327    
	return n; 
1990/0324    
} 
 
1992/0621/sys/src/9/port/devbit.c:598,6041992/0622/sys/src/9/port/devbit.c:611,619
1990/11211    
		error(Egreg); 
1990/0327    
 
1990/0721    
	isoff = 0; 
1992/0622    
	qlock(&bit); 
1990/0721    
	if(waserror()){ 
1992/0622    
		qunlock(&bit); 
1990/0721    
		if(isoff) 
			cursoron(1); 
		nexterror(); 
1992/0621/sys/src/9/port/devbit.c:1001,10481992/0622/sys/src/9/port/devbit.c:1016,1021
1990/0613    
			m -= 11; 
1990/06111    
			break; 
 
1990/0329    
		case 's': 
			/* 
1992/0209    
			 * subfstring 
1990/0329    
			 *	's'		1 
			 *	id		2 
			 *	pt		8 
1992/0209    
			 *	subfont id	2 
1990/06111    
			 *	code		2 
1990/0329    
			 * 	string		n (null terminated) 
			 */ 
			if(m < 16) 
1990/11211    
				error(Ebadblt); 
1990/0329    
			v = GSHORT(p+1); 
1992/0621    
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) 
1990/11211    
				error(Ebadbitmap); 
1990/0504    
			off = 0; 
1991/0706    
			fc = GSHORT(p+13) & 0xF; 
			if(v == 0){ 
				if(flipping) 
					fc = flipD[fc]; 
1990/0504    
				off = 1; 
1991/0706    
			} 
1990/0329    
			pt.x = GLONG(p+3); 
			pt.y = GLONG(p+7); 
			v = GSHORT(p+11); 
1992/0621    
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0) 
1990/11211    
				error(Ebadblt); 
1990/0329    
			p += 15; 
			m -= 15; 
			q = memchr(p, 0, m); 
			if(q == 0) 
1990/11211    
				error(Ebadblt); 
1990/0721    
			if(off && !isoff){ 
1990/0504    
				cursoroff(1); 
1990/0721    
				isoff = 1; 
			} 
1992/0208    
			gsubfstring(dst, pt, f, (char*)p, fc); 
1990/0329    
			q++; 
			m -= q-p; 
			p = q; 
			break; 
                 
		case 't': 
			/* 
			 * texture 
1992/0621/sys/src/9/port/devbit.c:1234,12461992/0622/sys/src/9/port/devbit.c:1207,1219
1992/0209    
			if(m < 9) 
				error(Ebadblt); 
			v = GSHORT(p+1); 
1992/0621    
			if(v<0 || v>=conf.nfont || (ff=bit.font[v])==0) 
1992/0622    
			if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0) 
1992/0209    
				error(Ebadblt); 
			l = GSHORT(p+3); 
			if(l >= NFCACHE+NFLOOK) 
				error(Ebadblt); 
			v = GSHORT(p+5); 
1992/0621    
			if(v<0 || v>=conf.nsubfont || (f=bit.subfont[v])==0) 
1992/0622    
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0) 
1992/0209    
				error(Ebadblt); 
			nw = GSHORT(p+7); 
			if(nw >= f->n) 
1992/0621/sys/src/9/port/devbit.c:1286,12911992/0622/sys/src/9/port/devbit.c:1259,1265
1991/0614    
	poperror(); 
1990/0721    
	if(isoff) 
		cursoron(1); 
1992/0622    
	qunlock(&bit); 
1990/0324    
	return n; 
} 
 
1992/0621/sys/src/9/port/devbit.c:1292,13031992/0622/sys/src/9/port/devbit.c:1266,1277
1992/0621    
int 
1992/0209    
bitalloc(Rectangle rect, int ld) 
{ 
1992/0622    
	Arena *a, *ea, *na, *aa; 
1992/0621    
	GBitmap *b, **bp, **ep; 
1992/0209    
	ulong l, ws, nw; 
	long t; 
1992/0621    
	int i; 
1992/0622    
	int i, try; 
1992/0209    
 
1992/0621    
print("bitalloc %lux\n", bit.wfree); 
1992/0209    
	ws = 1<<(5-ld);	/* pixels per word */ 
1992/0621    
	if(rect.min.x >= 0){ 
1992/0519    
		l = (rect.max.x+ws-1)/ws; 
1992/0621/sys/src/9/port/devbit.c:1308,13241992/0622/sys/src/9/port/devbit.c:1282,1339
1992/0209    
		l = (t+rect.max.x+ws-1)/ws; 
	} 
	nw = l*Dy(rect); 
	if(bit.wfree+2+nw > bit.words+bit.nwords){ 
		bitcompact(); 
		if(bit.wfree+2+nw > bit.words+bit.nwords) 
			error(Enobitstore); 
1992/0622    
	ea = &bit.arena[bit.narena]; 
 
	/* first try easy fit */ 
	for(a=bit.arena; a<ea; a++){ 
		if(a->words == 0) 
			continue; 
		if(a->wfree+HDR+nw <= a->words+a->nwords) 
			goto found; 
1992/0209    
	} 
1992/0622    
 
	/* compact and try again */ 
	bitcompact(); 
	aa = 0; 
	for(a=bit.arena; a<ea; a++){ 
		if(a->words == 0){ 
			if(aa == 0) 
				aa = a; 
			continue; 
		} 
		if(a->wfree+HDR+nw <= a->words+a->nwords) 
			goto found; 
	} 
 
	/* need new arena */ 
	if(aa) 
		a = aa; 
	else{ 
		na = bit.arena; 
		bit.arena = smalloc((bit.narena+DMAP)*sizeof(Arena)); 
		memmove(bit.arena, na, bit.narena*sizeof(Arena)); 
		free(na); 
		a = bit.arena+bit.narena; 
		bit.narena += DMAP; 
	} 
	a->nwords = gscreen.width*gscreen.r.max.y+HDR; 
	if(a->nwords < HDR+nw) 
		a->nwords = HDR+nw; 
	a->words = xalloc(a->nwords*sizeof(ulong)); 
	if(a->words == 0) 
		error(Enobitstore); 
	a->wfree = a->words; 
	a->nbusy = 0; 
	 
    found: 
1992/0621    
	b = smalloc(sizeof(GBitmap)); 
1992/0209    
	*bit.wfree++ = nw; 
1992/0621    
	*bit.wfree++ = (ulong)b; 
	b->base = bit.wfree; 
1992/0622    
	*a->wfree++ = nw; 
	*a->wfree++ = (ulong)a; 
	*a->wfree++ = (ulong)b; 
	b->base = a->wfree; 
1992/0621    
	memset(b->base, 0, nw*sizeof(ulong)); 
1992/0209    
	bit.wfree += nw; 
1992/0622    
	a->wfree += nw; 
	a->nbusy++; 
1992/0621    
	b->zero = l*rect.min.y; 
1992/0209    
	if(rect.min.x >= 0) 
1992/0621    
		b->zero += rect.min.x/ws; 
1992/0621/sys/src/9/port/devbit.c:1350,13551992/0622/sys/src/9/port/devbit.c:1365,1376
1990/0324    
void 
1992/0621    
bitfree(GBitmap *b) 
1990/0327    
{ 
1992/0622    
	Arena *a; 
 
	a = (Arena*)(b->base[-2]); 
	a->nbusy--; 
	if(a->nbusy == 0) 
		arenafree(a); 
1992/0621    
	b->base[-1] = 0; 
	free(b); 
1990/0327    
} 
1992/0621/sys/src/9/port/devbit.c:1370,13751992/0622/sys/src/9/port/devbit.c:1391,1403
1992/0621    
} 
 
void 
1992/0622    
arenafree(Arena *a) 
{ 
	xfree(a->words); 
	a->words = 0; 
} 
 
void 
1992/0209    
bitstring(GBitmap *bp, Point pt, GFont *f, uchar *p, long l, Fcode fc) 
{ 
	int full; 
1992/0621/sys/src/9/port/devbit.c:1435,14631992/0622/sys/src/9/port/devbit.c:1463,1527
1992/0209    
	gbitblt(f->b, Pt(c->x, f->ascent-subf->ascent), subf->bits, rect, S); 
} 
 
1990/08101    
QLock	bitlock; 
                 
1990/0327    
void 
bitcompact(void) 
{ 
	ulong *p1, *p2; 
1992/0622    
	Arena *a, *b, *ea, *na; 
	ulong *p1, *p2, n; 
1990/0327    
 
1990/08101    
	qlock(&bitlock); 
1990/0327    
	p1 = p2 = bit.words; 
	while(p2 < bit.wfree){ 
		if(p2[1] == 0){ 
			p2 += 2 + p2[0]; 
1992/0622    
	ea = &bit.arena[bit.narena]; 
	for(a=bit.arena; a<ea; a++){ 
		if(a->words == 0) 
1990/0327    
			continue; 
1992/0622    
		/* first compact what's here */ 
		p1 = p2 = a->words; 
		while(p2 < a->wfree){ 
			n = HDR+p2[0]; 
			if(p2[2] == 0){ 
				p2 += n; 
				continue; 
			} 
			if(p1 != p2){ 
				memmove(p1, p2, n*sizeof(ulong)); 
				((GBitmap*)p1[2])->base = p1+HDR; 
			} 
			p2 += n; 
			p1 += n; 
1990/0327    
		} 
		if(p1 != p2){ 
1991/0318    
			memmove(p1, p2, (2+p2[0])*sizeof(ulong)); 
1990/0902    
			((GBitmap*)p1[1])->base = p1+2; 
1992/0622    
		/* now pull stuff from later arena to fill this one */ 
		na = a+1; 
		while(na<ea && p1<a->words+a->nwords){ 
			p2 = na->words; 
			if(p2 == 0){ 
				na++; 
				continue; 
			} 
			while(p2 < na->wfree){ 
				n = HDR+p2[0]; 
				if(p2[2] == 0){ 
					p2 += n; 
					continue; 
				} 
				if(p1+n < a->words+a->nwords){ 
					memmove(p1, p2, n*sizeof(ulong)); 
					((GBitmap*)p1[2])->base = p1+HDR; 
					/* block now in new arena... */ 
					p1[1] = (ulong)a; 
					a->nbusy++; 
					/* ... not in old arena */ 
					na->nbusy--; 
					p2[2] = 0; 
					p1 += n; 
				} 
				p2 += n; 
			} 
			na++; 
1990/0327    
		} 
		p2 += 2 + p1[0]; 
		p1 += 2 + p1[0]; 
1992/0622    
		a->wfree = p1; 
1990/0327    
	} 
	bit.wfree = p1; 
1990/08101    
	qunlock(&bitlock); 
1992/0622    
	for(a=bit.arena; a<ea && a->words; a++) 
		if(a->nbusy == 0) 
			arenafree(a); 
1990/0329    
} 
 
void 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)