Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/devbit.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/devbit.c 1990/0324
## diff -e /dev/null /n/bootesdump/1990/0324/sys/src/9/68020/devbit.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"

#include	"devtab.h"

#include	"gnot.h"

extern	Bitmap	screen;

struct{
	Ref;
	int	bltuse;
	QLock	blt;		/* a group of bitblts in a single write is atomic */
}bit;

enum{
	Qdir,
	Qbitblt,
};

Dirtab bitdir[]={
	"bitblt",	Qbitblt,	0,			0600,
};

#define	NBIT	(sizeof bitdir/sizeof(Dirtab))

void
bitreset(void)
{
}

void
bitinit(void)
{
	lock(&bit);
	bit.bltuse = 0;
	unlock(&bit);
}

Chan*
bitattach(char *spec)
{
	return devattach('b', spec);
}

Chan*
bitclone(Chan *c, Chan *nc)
{
	nc = devclone(c, nc);
	if(c->qid != CHDIR)
		incref(&bit);
}

int
bitwalk(Chan *c, char *name)
{
	return devwalk(c, name, bitdir, NBIT, devgen);
}

void
bitstat(Chan *c, char *db)
{
	devstat(c, db, bitdir, NBIT, devgen);
}

Chan *
bitopen(Chan *c, int omode)
{
	if(c->qid == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
	}else{
		/*
		 * Always open #b/bitblt first
		 */
		lock(&bit);
		if((c->qid==Qbitblt && bit.bltuse)
		|| (c->qid!=Qbitblt && !bit.bltuse)){
			unlock(&bit);
			error(0, Einuse);
		}
		unlock(&bit);
		incref(&bit);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

void
bitcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
}

void
bitremove(Chan *c)
{
	error(0, Eperm);
}

void
bitwstat(Chan *c, char *db)
{
	error(0, Eperm);
}

void
bitclose(Chan *c)
{
	if(c->qid != CHDIR){
		lock(&bit);
		if(--bit.ref == 0)
			bit.bltuse = 0;
		unlock(&bit);
	}
}

long
bitread(Chan *c, void *va, long n)
{
	if(c->qid & CHDIR)
		return devdirread(c, va, n, bitdir, NBIT, devgen);

	error(0, Egreg);
}

#define	SHORT(p)	(((p)[0]<<0) | ((p)[1]<<8))
#define	LONG(p)		((SHORT(p)<<0) | (SHORT(p+2)<<16))

long
bitwrite(Chan *c, void *va, long n)
{
	uchar *p;
	long m;
	long v;
	Point pt;
	Rectangle rect;
	Bitmap *src, *dst;

	if(c->qid == CHDIR)
		error(0, Eisdir);

	p = va;
	m = n;
	switch(c->qid){
	case Qbitblt:
		qlock(&bit.blt);
		if(waserror()){
			qunlock(&bit.blt);
			nexterror();
		}
		while(m > 0)
			switch(*p){
			case 'b':
				if(m < 31)
					error(0, Ebadblt);
				v = SHORT(p+1);
				if(v != 0)		/* BUG */
					error(0, Ebadblt);
				dst = &screen;
				pt.x = LONG(p+3);
				pt.y = LONG(p+7);
				v = SHORT(p+11);
				if(v != 0)		/* BUG */
					error(0, Ebadblt);
				src = &screen;
				rect.min.x = LONG(p+13);
				rect.min.y = LONG(p+17);
				rect.max.x = LONG(p+21);
				rect.max.y = LONG(p+25);
				v = SHORT(p+29);
				bitblt(dst, pt, src, rect, v);
				m -= 31;
				p += 31;
				break;
			default:
				error(0, Ebadblt);
			}
		qunlock(&bit.blt);
		break;

	default:
		error(0, Egreg);
	}
	return n;
}

void
bituserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
biterrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}
.
## diffname port/devbit.c 1990/0327
## diff -e /n/bootesdump/1990/0324/sys/src/9/68020/devbit.c /n/bootesdump/1990/0327/sys/src/9/68020/devbit.c
203a
}

void
bitfree(Bitmap *bp)
{
	bp->base[1] = 0;
	bp->ldepth = -1;
	bp->base = (ulong*)bit.free;
	bit.free = bp;
}

void
bitcompact(void)
{
	ulong *p1, *p2;

print("bitcompact\n");
	p1 = p2 = bit.words;
	while(p2 < bit.wfree){
		if(p2[1] == 0){
			p2 += 2 + p2[0];
			continue;
		}
		if(p1 != p2){
			memcpy(p1, p2, (2+p2[0])*sizeof(ulong));
			((Bitmap*)p1[1])->base = p1+2;
		}
		p2 += 2 + p1[0];
		p1 += 2 + p1[0];
	}
	bit.wfree = p1;
print("bitcompact done\n");
.
188,190c
		case 'b':
			/*
			 * bitblt
			 *	'b'		1
			 *	dst id		2
			 *	dst Point	8
			 *	src id		2
			 *	src Rectangle	16
			 *	code		2
			 */
			if(m < 31)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth < 0)
				error(0, Ebadblt);
			pt.x = GLONG(p+3);
			pt.y = GLONG(p+7);
			v = GSHORT(p+11);
			src = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || src->ldepth < 0)
				error(0, Ebadblt);
			rect.min.x = GLONG(p+13);
			rect.min.y = GLONG(p+17);
			rect.max.x = GLONG(p+21);
			rect.max.y = GLONG(p+25);
			v = GSHORT(p+29);
			bitblt(dst, pt, src, rect, v);
			m -= 31;
			p += 31;
			break;

		case 'f':
			/*
			 * free
			 *	'f'		1
			 *	id		2
			 */
			if(m < 3)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v >= conf.nbitmap || dst->ldepth<0)
				error(0, Ebadblt);
			bitfree(dst);
			m -= 3;
			p += 3;
			break;
		}

	qunlock(&bit.blt);
.
185,186c
			nw = l*Dy(rect);
			if(bit.wfree+l+2 > bit.words+bit.nwords){
				bitcompact();
				if(bit.wfree+l+1 > bit.words+bit.nwords)
					error(0, Enobitstore);
			}
			bp = bit.free;
			bit.free = (Bitmap*)(bp->base);
			*bit.wfree++ = nw;
			*bit.wfree++ = (ulong)bp;
			bp->base = bit.wfree;
			memset(bp->base, 0, nw*sizeof(ulong));
			bit.wfree += nw;
			bp->zero = l*rect.min.y;
			if(rect.min.x >= 0)
				bp->zero += rect.min.x/ws;
			else
				bp->zero -= (-rect.min.x+ws-1)/ws;
			bp->zero = -bp->zero;
			bp->width = l;
			bp->ldepth = v;
			bp->rect = rect;
			bp->cache = 0;
			bit.lastid = bp-bit.map;
			m -= 18;
			p += 18;
			break;
.
183a
			v = *(p+1);
			if(v != 0)	/* BUG */
				error(0, Ebadblt);
			ws = 1<<(5-v);	/* pixels per word */
			if(bit.free == 0)
				error(0, Enobitmap);
			rect.min.x = GLONG(p+2);
			rect.min.y = GLONG(p+6);
			rect.max.x = GLONG(p+10);
			rect.max.y = GLONG(p+14);
			if(rect.min.x >= 0)
				l = (rect.max.x+ws-1)/ws - rect.min.x/ws;
			else{	/* make positive before divide */
				long t;
				t = (-rect.min.x)+ws-1;
				t = (t/ws)*ws;
				l = (t+rect.max.x+ws-1)/ws;
.
151,182c
	qlock(&bit.blt);
	if(waserror()){
		qunlock(&bit.blt);
		nexterror();
	}
	while(m > 0)
		switch(*p){
		case 'a':
			/*
			 * allocate:
			 *	'a'		1
			 *	ldepth		1
			 *	Rectangle	16
			 * next read returns allocated bitmap id
			 */
			if(m < 18)
.
148a
	if(c->qid != Qbitblt)
		error(0, Egreg);

.
144c
	Bitmap *bp, *src, *dst;
.
141a
	ulong l, nw, ws;
.
133,134d
130c
	if(c->qid != Qbitblt)
		error(0, Egreg);
	p = va;
	qlock(&bit.blt);
	if(waserror()){
		qunlock(&bit.blt);
		nexterror();
	}
	/*
	 * Fuss about and figure out what to say.
	 */
	if(bit.lastid > 0){
		if(n < 3)
			error(0, Ebadblt);
		p[0] = 'A';
		p[1] = bit.lastid;
		p[2] = bit.lastid>>8;
		bit.lastid = -1;
		n = 3;
		goto done;
	}
	error(0, Ebadblt);

    done:
	qunlock(&bit.blt);
	return n;
.
126a
	uchar *p;

.
123a
#define	GSHORT(p)		(((p)[0]<<0) | ((p)[1]<<8))
#define	GLONG(p)		((GSHORT(p)<<0) | (GSHORT(p+2)<<16))

.
119a
		}
.
117,118c
		lock(&bit);			/* FREE ALL THE BITMAPS: BUG */
		if(--bit.ref == 0){
			for(i=1,bp=&bit.map[1]; i<conf.nbitmap; i++,bp++)
				if(bp->ldepth >= 0)
					bitfree(bp);
.
115a
	int i;
	Bitmap *bp;

.
85a
		bit.lastid = -1;
.
81,82c
		if(bit.bltuse){
.
77,79d
33a
	int i;
	Bitmap *bp;

	bit.map = ialloc(conf.nbitmap * sizeof(Bitmap), 0);
	for(i=0,bp=bit.map; i<conf.nbitmap; i++,bp++){
		bp->ldepth = -1;
		bp->base = (ulong*)(bp+1);
	}
	bp--;
	bp->base = 0;
	bit.map[0] = screen;	/* bitmap 0 is screen */
	bit.free = bit.map+1;
	bit.lastid = -1;
	bit.words = ialloc(conf.nbitbyte, 0);
	bit.nwords = conf.nbitbyte/sizeof(ulong);
	bit.wfree = bit.words;
.
19a
#define	FREE	0x80000000
void	bitcompact(void);
void	bitfree(Bitmap*);
extern	Bitmap	screen;

.
17a
	Bitmap	*map;		/* arena */
	Bitmap	*free;		/* free list */
	ulong	*words;		/* storage */
	ulong	nwords;		/* total in arena */
	ulong	*wfree;		/* pointer to next free word */
	int	lastid;		/* last allocated bitmap id */
.
12c
/*
 * Some fields in Bitmaps are overloaded:
 *	ldepth = -1 means free.
 *	base is next pointer when free.
 * Arena is a word containing N, followed by a pointer to its bitmap,
 * followed by N blocks.  The bitmap pointer is zero if block is free. 
 */
.
## diffname port/devbit.c 1990/0329
## diff -e /n/bootesdump/1990/0327/sys/src/9/68020/devbit.c /n/bootesdump/1990/0329/sys/src/9/68020/devbit.c
378a
}

void
mousebuttons(int b)
{
	if(mouse.buttons != b){
		print("buttons %x\n", b);
		mouse.buttons = b;
	}
.
333d
330a

		case 's':
			/*
			 * string
			 *	's'		1
			 *	id		2
			 *	pt		8
			 *	font id		2
			 *	fcode		2
			 * 	string		n (null terminated)
			 */
			if(m < 16)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			pt.x = GLONG(p+3);
			pt.y = GLONG(p+7);
			v = GSHORT(p+11);
			if(v != 0)	/* BUG */
				error(0, Ebadblt);
			v = GSHORT(p+13);
			p += 15;
			m -= 15;
			q = memchr(p, 0, m);
			if(q == 0)
				error(0, Ebadblt);
			string(dst, pt, &defont0/*BUG*/, (char*)p, v);
			q++;
			m -= q-p;
			p = q;
			break;

		case 't':
			/*
			 * texture
			 *	't'		1
			 *	dst id		2
			 *	Rectangle	16
			 *	src id		2
			 *	fcode		2
			 */
			if(m < 23)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			rect.min.x = GLONG(p+3);
			rect.min.y = GLONG(p+7);
			rect.max.x = GLONG(p+11);
			rect.max.y = GLONG(p+15);
			v = GSHORT(p+19);
			src = &bit.map[v];
			if(v>=conf.nbitmap || src->ldepth<0)
				error(0, Ebadbitmap);
			if(src->r.min.x!=0 || src->r.min.y!=0 || src->r.max.x!=16 || src->r.max.y!=16)
				error(0, Ebadblt);
			v = GSHORT(p+21);
			{
				int i;
				Texture t;

				for(i=0; i<16; i++)
					t.bits[i] = src->base[i]>>16;
				texture(dst, rect, &t, v);
			}
			m -= 23;
			p += 23;
			break;

		case 'w':
			/*
			 * write
			 *	'w'		1
			 *	dst id		2
			 *	miny		4
			 *	maxy		4
			 *	data		bytewidth*(maxy-miny)
			 */
			if(m < 11)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			miny = GLONG(p+3);
			maxy = GLONG(p+7);
			ws = 1<<(3-dst->ldepth);	/* pixels per byte */
			/* set l to number of bytes of incoming data per scan line */
			if(dst->r.min.x >= 0)
				l = (dst->r.max.x+ws-1)/ws - dst->r.min.x/ws;
			else{	/* make positive before divide */
				t = (-dst->r.min.x)+ws-1;
				t = (t/ws)*ws;
				l = (t+dst->r.max.x+ws-1)/ws;
			}
			p += 11;
			m -= 11;
			if(m < l*(maxy-miny))
				error(0, Ebadblt);
			for(y=miny; y<maxy; y++){
				q = (uchar*)addr(dst, Pt(dst->r.min.x, y));
				q += (dst->r.min.x&((sizeof(ulong))*ws-1))/8;
				for(x=0; x<l; x++)
					*q++ = U2K(*p++);
				m -= l;
			}
			break;
.
325,326c
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
.
304c
				error(0, Ebadbitmap);
.
298c
				error(0, Ebadbitmap);
.
276c
			bp->r = rect;
.
250d
226a
		default:
			pprint("bitblt request 0x%x\n", *p);
			error(0, Ebadblt);

.
220,224d
204,206c
	uchar *p, *q;
	long m, v, miny, maxy, t, x, y;
.
196d
187,188c
		PSHORT(p+1, bit.lastid);
.
183a
		/*
		 * allocate:
		 *	'A'		1
		 *	bitmap id	2
		 */
.
182a
	if(bit.init){
		/*
		 * init:
		 *	'I'		1
		 *	ldepth		2
		 * 	rectangle	16
		 */
		if(n < 19)
			error(0, Ebadblt);
		p[0] = 'I';
		PSHORT(p+1, screen.ldepth);
		PLONG(p+3, screen.r.min.x);
		PLONG(p+7, screen.r.min.y);
		PLONG(p+11, screen.r.max.x);
		PLONG(p+15, screen.r.max.y);
		bit.init = 0;
		goto done;
	}
.
175,179d
163a
/*
 * These macros turn user-level (high bit at left) into internal (whatever)
 * bit order.  On the gnot they're trivial.
 */
#define	U2K(x)	(x)
#define	K2U(x)	(x)

.
162a
#define	PSHORT(p, v)		((p)[0]=(v), (p)[1]=((v)>>8))
#define	PLONG(p, v)		(PSHORT(p, (v)), PSHORT(p+2, (v)>>16))
.
150c
		lock(&bit);
.
115a
		bit.init = 1;
.
43a
	"mouse",	Qmouse,		0,			0600,
.
39a
	Qmouse,
.
35a
Mouse	mouse;
.
29a
	int	init;		/* freshly opened; init message pending */
.
23d
12a
 * Device (#b/bitblt) is exclusive use on open, so no locks are necessary
 * for i/o
 */

/*
.
11a
extern Font	defont0;	/* BUG */

.
## diffname port/devbit.c 1990/03291
## diff -e /n/bootesdump/1990/0329/sys/src/9/68020/devbit.c /n/bootesdump/1990/03291/sys/src/9/68020/devbit.c
452a
			if(miny>maxy || miny<dst->r.min.y || maxy>dst->r.max.y)
				error(0, Ebadblt);
.
213a
		n = 18;
.
208,212c
		p[1] = screen.ldepth;
		PLONG(p+2, screen.r.min.x);
		PLONG(p+6, screen.r.min.y);
		PLONG(p+10, screen.r.max.x);
		PLONG(p+14, screen.r.max.y);
.
205c
		if(n < 18)
.
202c
		 *	ldepth		1
.
## diffname port/devbit.c 1990/0504
## diff -e /n/bootesdump/1990/03291/sys/src/9/68020/devbit.c /n/bootesdump/1990/0504/sys/src/9/68020/devbit.c
529,531c
	int i;

	lock(&cursor);
	for(i=0; i<16; i++){
		setbits[i] = cursor.set[i]<<16;
		clrbits[i] = cursor.clr[i]<<16;
	}
	unlock(&cursor);
}

void
cursoron(int dolock)
{
	if(dolock)
		lock(&cursor);
	if(cursor.visible++ == 0){
		cursor.r.min = mouse.xy;
		cursor.r.max = add(mouse.xy, Pt(16, 16));
		cursor.r = raddp(cursor.r, cursor.offset);
		bitblt(&cursorback, Pt(0, 0), &screen, cursor.r, S);
		bitblt(&screen, add(mouse.xy, cursor.offset),
			&clr, Rect(0, 0, 16, 16), D&~S);
		bitblt(&screen, add(mouse.xy, cursor.offset),
			&set, Rect(0, 0, 16, 16), S|D);
	}
	if(dolock)
		unlock(&cursor);
}

void
cursoroff(int dolock)
{
	if(dolock)
		lock(&cursor);
	if(--cursor.visible == 0)
		bitblt(&screen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
	if(dolock)
		unlock(&cursor);
}

void
mousebuttons(int b)	/* called splhi */
{
	mouse.buttons = b;
	mouse.changed = 1;
	wakeup(&mouse.r);
}

void
mouseclock(void)	/* called splhi */
{
	int x, y;

	if(mouse.track && canlock(&cursor)){
		x = mouse.xy.x + mouse.dx;
		if(x < screen.r.min.x)
			x = screen.r.min.x;
		if(x >= screen.r.max.x)
			x = screen.r.max.x;
		y = mouse.xy.y + mouse.dy;
		if(y < screen.r.min.y)
			y = screen.r.min.y;
		if(y >= screen.r.max.y)
			y = screen.r.max.y;
		cursoroff(0);
		mouse.xy = Pt(x, y);
		cursoron(0);
		mouse.dx = 0;
		mouse.dy = 0;
		mouse.track = 0;
		mouse.changed = 1;
		unlock(&cursor);
		wakeup(&mouse.r);
.
527c
cursortobitmap(void)
.
475a
			if(off)
				cursoron(1);
.
468a
			if(off)
				cursoroff(1);
.
451a
			off = 0;
			if(v == 0)
				off = 1;
.
431a
				if(off)
					cursoron(1);
.
430a
				if(off)
					cursoroff(1);
.
413a
			off = 0;
			if(v == 0)
				off = 1;
.
393a
			if(off)
				cursoron(1);
.
392a
			if(off)
				cursoroff(1);
.
381a
			off = 0;
			if(v == 0)
				off = 1;
.
344a
			if(off)
				cursoron(1);
.
343a
			if(off)
				cursoroff(1);
.
338a
			if(v == 0)
				off = 1;
.
332a
			off = 0;
			if(v == 0)
				off = 1;
.
243a
	int off;
.
84a
	cursoron(1);
.
76a
	cursortobitmap();
.
44a
struct{
	/*
	 * First three fields are known in l.s
	 */
	int	dx;		/* interrupt-time delta */
	int	dy;
	int	track;		/* update cursor on screen */
	Mouse;
	int	changed;	/* mouse structure changed since last read */
	Rendez	r;
}mouse;

struct{
	Cursor;
	Lock;
	int	visible;	/* on screen */
	Rectangle r;		/* location */
}cursor =
{
	{{0, 0},
	{0xFFE0, 0xFFE0, 0xFFC0, 0xFF00,
	 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
	 0xE7F0, 0xE3F8, 0xC1FC, 0x00FE,
	 0x007F, 0x003E, 0x001C, 0x0008,
	},
	{0x0000, 0x7FC0, 0x7F00, 0x7C00,
	 0x7E00, 0x7F00, 0x6F80, 0x67C0,
	 0x43E0, 0x41F0, 0x00F8, 0x007C,
	 0x003E, 0x001C, 0x0008, 0x0000,
	}},
};

ulong setbits[16];
Bitmap	set =
{
	setbits,
	0,
	1,
	0,
	{0, 0, 16, 16}
};

ulong clrbits[16];
Bitmap	clr =
{
	clrbits,
	0,
	1,
	0,
	{0, 0, 16, 16}
};

ulong cursorbackbits[16];
Bitmap cursorback =
{
	cursorbackbits,
	0,
	1,
	0,
	{0, 0, 16, 16}
};

void	cursortobitmap(void);
void	cursoron(int);
void	cursoroff(int);

.
43d
## diffname port/devbit.c 1990/0505
## diff -e /n/bootesdump/1990/0504/sys/src/9/68020/devbit.c /n/bootesdump/1990/0505/sys/src/9/68020/devbit.c
700a
}

int
mousechanged(void *m)
{
	return mouse.changed;
.
696a
		mouse.buttons = mouse.newbuttons;
.
676c
mouseclock(void)	/* called spl6 */
.
670,672c
	/*
	 * It is possible if you click very fast and get bad luck
	 * you could miss a button click (down up).  Doesn't seem
	 * likely or important enough to worry about.
	 */
	mouse.newbuttons = b;
	mouse.track = 1;		/* aggressive but o.k. */
	mouseclock();
.
668c
mousebuttons(int b)	/* called spl5 */
.
300d
298d
290,296c
		if(bit.init){
			/*
			 * init:
			 *	'I'		1
			 *	ldepth		1
			 * 	rectangle	16
			 */
			if(n < 18)
				error(0, Ebadblt);
			p[0] = 'I';
			p[1] = screen.ldepth;
			PLONG(p+2, screen.r.min.x);
			PLONG(p+6, screen.r.min.y);
			PLONG(p+10, screen.r.max.x);
			PLONG(p+14, screen.r.max.y);
			bit.init = 0;
			n = 18;
			break;
		}
		if(bit.lastid > 0){
			/*
			 * allocate:
			 *	'A'		1
			 *	bitmap id	2
			 */
			if(n < 3)
				error(0, Ebadblt);
			p[0] = 'A';
			PSHORT(p+1, bit.lastid);
			bit.lastid = -1;
			n = 3;
			break;
		}
		error(0, Ebadblt);

	default:
		error(0, Egreg);
.
286,288c
		 * Fuss about and figure out what to say.
.
274,284c
	    Again:
		while(mouse.changed == 0)
			sleep(&mouse.r, mousechanged, 0);
		lock(&cursor);
		if(mouse.changed == 0){
			unlock(&cursor);
			goto Again;
		}
		p = va;
		p[0] = 'm';
		p[1] = mouse.buttons;
		PLONG(p+2, mouse.xy.x);
		PLONG(p+6, mouse.xy.y);
		mouse.changed = 0;
		unlock(&cursor);
		n = 10;
		break;

	case Qbitblt:
		p = va;
.
272c
		if(n < 10)
.
267,270c
		 * mouse:
		 *	'm'		1
		 *	buttons		1
		 * 	point		8
.
259,265c
	switch(c->qid){
	case Qmouse:
.
108a
int	mousechanged(void*);
.
52a
	int	newbuttons;	/* interrupt time access only */
.
## diffname port/devbit.c 1990/0515
## diff -e /n/bootesdump/1990/0505/sys/src/9/68020/devbit.c /n/bootesdump/1990/0515/sys/src/9/68020/devbit.c
235d
190c
		if(bit.ref){
.
188c
	}else if(c->qid == Qbitblt){
.
151d
29d
## diffname port/devbit.c 1990/05151
## diff -e /n/bootesdump/1990/0515/sys/src/9/68020/devbit.c /n/bootesdump/1990/05151/sys/src/9/68020/devbit.c
227c
	if(c->qid!=CHDIR && (c->flag&COPEN)){
.
196d
194a
	}else
.
193a
		bit.ref = 1;
.
## diffname port/devbit.c 1990/05313
## diff -e /n/bootesdump/1990/05151/sys/src/9/68020/devbit.c /n/bootesdump/1990/05313/sys/src/9/68020/devbit.c
714d
661,662c
		setbits[i] = (c->set[2*i]<<24) + (c->set[2*i+1]<<16);
		clrbits[i] = (c->clr[2*i]<<24) + (c->clr[2*i+1]<<16);
.
659a
	memcpy(&cursor, c, sizeof(Cursor));
.
655c
Cursortocursor(Cursor *c)
.
651d
636d
625c
	bp->base[-1] = 0;
.
505c
			string(dst, pt, defont/*BUG*/, (char*)p, v);
.
455a
		case 'c':
			/*
			 * cursorswitch
			 *	'c'		1
			 * nothing more: return to arrow; else
			 * 	Point		8
			 *	clr		32
			 *	set		32
			 */
			if(m == 1){
				cursoroff(1);
				Cursortocursor(&arrow);
				cursoron(1);
				m -= 1;
				p += 1;
				break;
			}
			if(m < 73)
				error(0, Ebadblt);
			curs.offset.x = GLONG(p+1);
			curs.offset.y = GLONG(p+5);
			memcpy(curs.clr, p+9, 2*16);
			memcpy(curs.set, p+41, 2*16);
			cursoroff(1);
			Cursortocursor(&curs);
			cursoron(1);
			m -= 73;
			p += 73;
			break;

.
390c
				if(bit.wfree+2+nw > bit.words+bit.nwords)
.
388c
			if(bit.wfree+2+nw > bit.words+bit.nwords){
.
371c
			if(v!=0 && v!=1)	/* BUG */
.
343a
	Cursor curs;
.
194a
		Cursortocursor(&arrow);
.
150a
	if(screen.ldepth > 1)
		panic("bitinit ldepth>1");
	cursorback.ldepth = screen.ldepth;
.
143c
	Cursortocursor(&arrow);
.
106c
void	Cursortocursor(Cursor*);
.
61,74c
}cursor;
.
55a
Cursor	arrow =
{
	{0, 0},
	{0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xC0, 0xFF, 0x00,
	 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xE0,
	 0xE7, 0xF0, 0xE3, 0xF8, 0xC1, 0xFC, 0x00, 0xFE,
	 0x00, 0x7F, 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08,
	},
	{0x00, 0x00, 0x7F, 0xC0, 0x7F, 0x00, 0x7C, 0x00,
	 0x7E, 0x00, 0x7F, 0x00, 0x6F, 0x80, 0x67, 0xC0,
	 0x43, 0xE0, 0x41, 0xF0, 0x00, 0xF8, 0x00, 0x7C,
	 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00,
	}
};

.
27c
struct
{
.
12c
extern Font	*defont;
.
## diffname port/devbit.c 1990/0604
## diff -e /n/bootesdump/1990/05313/sys/src/9/68020/devbit.c /n/bootesdump/1990/0604/sys/src/9/68020/devbit.c
508a
			break;

		case 'i':
			/*
			 * init
			 *
			 *	'i'		1
			 */
			bit.init = 1;
			m -= 1;
			p += 1;
.
199c
		bit.init = 0;
.
## diffname port/devbit.c 1990/06111
## diff -e /n/bootesdump/1990/0604/sys/src/9/68020/devbit.c /n/bootesdump/1990/06111/sys/src/9/68020/devbit.c
529c
			 *	code		2
.
521a
		case 'l':
			/*
			 * line segment
			 *
			 *	'l'		1
			 *	id		2
			 *	pt1		8
			 *	pt2		8
			 *	value		1
			 *	code		2
			 */
			if(m < 22)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			off = 0;
			if(v == 0)
				off = 1;
			pt1.x = GLONG(p+3);
			pt1.y = GLONG(p+7);
			pt2.x = GLONG(p+11);
			pt2.y = GLONG(p+15);
			t = p[19];
			v = GSHORT(p+20);
			if(off)
				cursoroff(1);
			segment(dst, pt1, pt2, t, v);
			if(off)
				cursoron(1);
			m -= 22;
			p += 22;
			break;

.
349c
	Point pt, pt1, pt2;
.
## diffname port/devbit.c 1990/0613
## diff -e /n/bootesdump/1990/06111/sys/src/9/68020/devbit.c /n/bootesdump/1990/0613/sys/src/9/68020/devbit.c
554a
			break;

		case 'r':
			/*
			 * read
			 *	'r'		1
			 *	src id		2
			 *	miny		4
			 *	maxy		4
			 */
			if(m < 11)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			src = &bit.map[v];
			if(v>=conf.nbitmap || src->ldepth<0)
				error(0, Ebadbitmap);
			miny = GLONG(p+3);
			maxy = GLONG(p+7);
			if(miny>maxy || miny<src->r.min.y || maxy>src->r.max.y)
				error(0, Ebadblt);
			bit.rid = v;
			bit.rminy = miny;
			bit.rmaxy = maxy;
			p += 11;
			m -= 11;
.
331a
		if(bit.rid >= 0){
			/*
			 * read
			 *	data		bytewidth*(maxy-miny)
			 */
			src = &bit.map[bit.rid];
			if(src->ldepth<0)
				error(0, 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(0, 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(0, Ebadblt);
			if(off)
				cursoroff(1);
			n = 0;
			p = va;
			for(y=miny; y<maxy; y++){
				q = (uchar*)addr(src, Pt(src->r.min.x, y));
				q += (src->r.min.x&((sizeof(ulong))*ws-1))/8;
				for(x=0; x<l; x++)
					*p++ = K2U(*q++);
				n += l;
			}
			if(off)
				cursoron(1);
			bit.rid = -1;
			break;
		}
.
261c
	uchar *p, *q;
	long miny, maxy, t, x, y;
	ulong l, nw, ws;
	int off;
	Bitmap *src;
.
198a
		bit.rid = -1;
.
36a
	int	rid;		/* read bitmap id */
	int	rminy;		/* read miny */
	int	rmaxy;		/* read maxy */
.
## diffname port/devbit.c 1990/0623
## diff -e /n/bootesdump/1990/0613/sys/src/9/68020/devbit.c /n/bootesdump/1990/0623/sys/src/9/68020/devbit.c
730c
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
.
696c
			if(v<0 || v>=conf.nbitmap || src->ldepth<0)
.
685c
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
.
664c
			string(dst, pt, f, (char*)p, v);
.
654c
			f = &bit.font[v];
			if(v<0 || v>=conf.nfont || f->bits==0 || f->bits->ldepth<0)
.
646c
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
.
619c
			if(v<0 || v>=conf.nbitmap || src->ldepth<0)
.
587c
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
.
571a
		case 'k':
			/*
			 * allocate font
			 *	'k'		1
			 *	n		2
			 *	height		1
			 *	ascent		1
			 *	bitmap id	2
			 *	fontchars	6*n
			 * next read returns allocated font id
			 */
			if(m < 7)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			if(v<0 || v>NINFO || m<7+6*(v+1))	/* BUG */
				error(0, Ebadblt);
			for(i=1; i<conf.nfont; i++)
				if(bit.font[i].bits == 0)
					goto fontfound;
			error(0, Enofont);
		fontfound:
			f = &bit.font[i];
			f->n = v;
			f->height = p[3];
			f->ascent = p[4];
			v = GSHORT(p+5);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			m -= 7;
			p += 7;
			fcp = f->info;
			for(i=0; i<=f->n; i++,fcp++){
				fcp->x = GSHORT(p);
				fcp->top = p[2];
				fcp->bottom = p[3];
				fcp->left = p[4];
				fcp->width = p[5];
				fcp->top = p[2];
				p += 6;
				m -= 6;
			}
			bit.lastfid = f - bit.font;
			f->bits = dst;
			break;

.
560a
		case 'g':
			/*
			 * free font (free bitmap separately)
			 *	'g'		1
			 *	id		2
			 */
			if(m < 3)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			f = &bit.font[v];
			if(v<0 || v>=conf.nfont || f->bits==0)
				error(0, Ebadbitmap);
			f->bits = 0;
			m -= 3;
			p += 3;
			break;

.
554c
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
.
402a
	Font *f;
.
401a
	Fontchar *fcp;
.
398c
	int off, i;
.
339a
		if(bit.lastfid > 0){
			/*
			 * allocate font:
			 *	'K'		1
			 *	font id		2
			 */
			if(n < 3)
				error(0, Ebadblt);
			p[0] = 'K';
			PSHORT(p+1, bit.lastfid);
			bit.lastfid = -1;
			n = 3;
			break;
		}
.
244a
			for(i=1,fp=&bit.font[1]; i<conf.nfont; i++,fp++)
				fp->bits = 0;
.
237a
	Font *fp;
.
201a
		bit.lastfid = -1;
.
148a
	bit.font = ialloc(conf.nfont * sizeof(Font), 0);
	bit.font[0] = *defont;
	for(i=1; i<conf.nfont; i++)
		bit.font[i].info = ialloc((NINFO+1)*sizeof(Fontchar), 0);
.
145a
	bit.lastfid = -1;
.
128a
#define	NINFO	150
.
35a
	int	lastfid;	/* last allocated font id */
.
34a
	Font	*font;		/* arena; looked up linearly BUG */
.
## diffname port/devbit.c 1990/06231
## diff -e /n/bootesdump/1990/0623/sys/src/9/68020/devbit.c /n/bootesdump/1990/06231/sys/src/9/68020/devbit.c
335d
333a
			if(n >= 18+3*12+6*(defont->n+1)){
				p += 18;
				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 = 18+3*12+6*(defont->n+1);
			}else
				n = 18;
.
324a
			 * if count great enough, also
			 *	font info	3*12
			 *	fontchars	6*(defont->n+1)
.
280c
	int off, j;
	Fontchar *i;
.
## diffname port/devbit.c 1990/0629
## diff -e /n/bootesdump/1990/06231/sys/src/9/68020/devbit.c /n/bootesdump/1990/0629/sys/src/9/68020/devbit.c
131c
#define	NINFO	257
.
## diffname port/devbit.c 1990/0707
## diff -e /n/bootesdump/1990/0629/sys/src/9/68020/devbit.c /n/bootesdump/1990/0707/sys/src/9/68020/devbit.c
643c
			 *	fontchars	6*(n+1)
.
## diffname port/devbit.c 1990/0709
## diff -e /n/bootesdump/1990/0707/sys/src/9/68020/devbit.c /n/bootesdump/1990/0709/sys/src/9/68020/devbit.c
426a

	case Qscreen:
		if(c->offset==0){
			if(n < 5*12)
				error(0, Eio);
			sprint(va, "%11d %11d %11d %11d %11d ",
				screen.ldepth, screen.r.min.x,
				screen.r.min.y, screen.r.max.x,
				screen.r.max.y);
			n = 5*12;
			break;
		}
		ws = 1<<(3-screen.ldepth);	/* pixels per byte */
		l = (screen.r.max.x+ws-1)/ws - screen.r.min.x/ws;
		t = c->offset-5*12;
		miny = t/l;
		maxy = (t+n)/l;
		if(miny >= screen.r.max.y)
			return 0;
		if(maxy >= screen.r.max.y)
			maxy = screen.r.max.y;
		n = 0;
		p = va;
		for(y=miny; y<maxy; y++){
			q = (uchar*)addr(&screen, Pt(0, y));
			for(x=0; x<l; x++)
				*p++ = K2U(*q++);
			n += l;
		}
		break;
.
127a
	"screen",	Qscreen,	0,			0400,
.
122a
	Qscreen,
.
## diffname port/devbit.c 1990/0721
## diff -e /n/bootesdump/1990/0709/sys/src/9/68020/devbit.c /n/bootesdump/1990/0721/sys/src/9/68020/devbit.c
907a
	if(isoff)
		cursoron(1);
.
903,904d
895a
				isoff = 1;
			}
.
894c
			if(off && !isoff){
.
852,853d
850a
					isoff = 1;
				}
.
849c
				if(off && !isoff){
.
807,808d
805a
				isoff = 1;
			}
.
804c
			if(off && !isoff){
.
742,743d
740a
				isoff = 1;
			}
.
739c
			if(off && !isoff){
.
617d
615c
			if(!isoff){
				cursoroff(1);
				isoff = 1;
			}
.
604d
602c
				if(!isoff){
					cursoroff(1);
					isoff = 1;
				}
.
586,587d
584a
				isoff = 1;
			}
.
583c
			if(off && !isoff){
.
487a
	isoff = 0;
	if(waserror()){
		if(isoff)
			cursoron(1);
		nexterror();
	}
.
474c
	int off, isoff, i;
.
## diffname port/devbit.c 1990/0722
## diff -e /n/bootesdump/1990/0721/sys/src/9/68020/devbit.c /n/bootesdump/1990/0722/sys/src/9/68020/devbit.c
757a
		case 'p':
			/*
			 * point
			 *
			 *	'p'		1
			 *	id		2
			 *	pt		8
			 *	value		1
			 *	code		2
			 */
			if(m < 14)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			off = 0;
			if(v == 0)
				off = 1;
			pt1.x = GLONG(p+3);
			pt1.y = GLONG(p+7);
			t = p[11];
			v = GSHORT(p+12);
			if(off && !isoff){
				cursoroff(1);
				isoff = 1;
			}
			point(dst, pt1, t, v);
			m -= 14;
			p += 14;
			break;

.
## diffname port/devbit.c 1990/0725
## diff -e /n/bootesdump/1990/0722/sys/src/9/68020/devbit.c /n/bootesdump/1990/0725/sys/src/9/68020/devbit.c
660c
				error(0, Ebadfont);
.
64c
	{1, 1},
.
## diffname port/devbit.c 1990/0726
## diff -e /n/bootesdump/1990/0725/sys/src/9/68020/devbit.c /n/bootesdump/1990/0726/sys/src/9/68020/devbit.c
660c
				error(0, Ebadbitmap);
.
64c
	{0, 0},
.
## diffname port/devbit.c 1990/0728
## diff -e /n/bootesdump/1990/0726/sys/src/9/68020/devbit.c /n/bootesdump/1990/0728/sys/src/9/68020/devbit.c
660c
				error(0, Ebadfont);
.
64c
	{1, 1},
.
## diffname port/devbit.c 1990/0730
## diff -e /n/bootesdump/1990/0728/sys/src/9/68020/devbit.c /n/bootesdump/1990/0730/sys/src/9/68020/devbit.c
64c
	{-1, -1},
.
## diffname port/devbit.c 1990/08101
## diff -e /n/bootesdump/1990/0730/sys/src/9/68020/devbit.c /n/bootesdump/1990/08101/sys/src/9/68020/devbit.c
994a
	qunlock(&bitlock);
.
980a
	qlock(&bitlock);
.
975a
QLock	bitlock;

Bitmap *
id2bit(int k)
{
	Bitmap *bp;
	bp = &bit.map[k];
	if(k<0 || k>=conf.nbitmap || bp->ldepth < 0)
		error(0, Ebadbitmap);
	return bp;
}

.
## diffname port/devbit.c 1990/0826
## diff -e /n/bootesdump/1990/08101/sys/src/9/68020/devbit.c /n/bootesdump/1990/0826/sys/src/9/68020/devbit.c
947a

		case 'x':
			/*
			 * cursorset
			 *
			 *	'x'		1
			 *	pt		8
			 */
			if(m < 9)
				error(0, Ebadblt);
			pt1.x = GLONG(p+1);
			pt1.y = GLONG(p+5);
			mouse.xy = pt1;
			mouse.track = 1;
			mouseclock();
			m -= 9;
			p += 9;
			break;
.
## diffname port/devbit.c 1990/0902
## diff -e /n/bootesdump/1990/0826/sys/src/9/68020/devbit.c /n/bootesdump/1990/0902/sys/src/9/68020/devbit.c
1068c
		gbitblt(&screen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
.
1055c
		gbitblt(&screen, add(mouse.xy, cursor.offset),
.
1052,1053c
		gbitblt(&cursorback, Pt(0, 0), &screen, cursor.r, S);
		gbitblt(&screen, add(mouse.xy, cursor.offset),
.
1020c
			((GBitmap*)p1[1])->base = p1+2;
.
999c
	GBitmap *bp;
.
996c
GBitmap *
.
986c
bitfree(GBitmap *bp)
.
895c
				gtexture(dst, rect, &t, v);
.
887c
				GTexture t;
.
850c
			gstring(dst, pt, f, (char*)p, v);
.
785c
			gpoint(dst, pt1, t, v);
.
753c
			gsegment(dst, pt1, pt2, t, v);
.
593c
			gbitblt(dst, pt, src, rect, v);
.
536c
			bit.free = (GBitmap*)(bp->base);
.
479,480c
	GBitmap *bp, *src, *dst;
	GFont *f;
.
284c
	GBitmap *src;
.
248,249c
	GBitmap *bp;
	GFont *fp;
.
155c
	bit.font = ialloc(conf.nfont * sizeof(GFont), 0);
.
141c
	bit.map = ialloc(conf.nbitmap * sizeof(GBitmap), 0);
.
139c
	GBitmap *bp;
.
105c
GBitmap cursorback =
.
95c
GBitmap	clr =
.
85c
GBitmap	set =
.
46,47c
void	bitfree(GBitmap*);
extern	GBitmap	screen;
.
35c
	GFont	*font;		/* arena; looked up linearly BUG */
.
30,31c
	GBitmap	*map;		/* arena */
	GBitmap	*free;		/* free list */
.
20c
 * Some fields in GBitmaps are overloaded:
.
12c
extern GFont	*defont;
.
10c
#include	<gnot.h>
.
## diffname port/devbit.c 1990/0911
## diff -e /n/bootesdump/1990/0902/sys/src/9/68020/devbit.c /n/bootesdump/1990/0911/sys/src/9/68020/devbit.c
942c
				q += (dst->r.min.x&((sizeof(ulong))*ws-1))/ws;
.
418c
				q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws;
.
## diffname port/devbit.c 1990/0912
## diff -e /n/bootesdump/1990/0911/sys/src/9/68020/devbit.c /n/bootesdump/1990/0912/sys/src/9/68020/devbit.c
1097,1100c
		if(y < gscreen.r.min.y)
			y = gscreen.r.min.y;
		if(y >= gscreen.r.max.y)
			y = gscreen.r.max.y;
.
1092,1095c
		if(x < gscreen.r.min.x)
			x = gscreen.r.min.x;
		if(x >= gscreen.r.max.x)
			x = gscreen.r.max.x;
.
1068c
		gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
.
1055c
		gbitblt(&gscreen, add(mouse.xy, cursor.offset),
.
1052,1053c
		gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S);
		gbitblt(&gscreen, add(mouse.xy, cursor.offset),
.
941c
				q = (uchar*)gaddr(dst, Pt(dst->r.min.x, y));
.
453c
			q = (uchar*)gaddr(&gscreen, Pt(0, y));
.
448,449c
		if(maxy >= gscreen.r.max.y)
			maxy = gscreen.r.max.y;
.
446c
		if(miny >= gscreen.r.max.y)
.
441,442c
		ws = 1<<(3-gscreen.ldepth);	/* pixels per byte */
		l = (gscreen.r.max.x+ws-1)/ws - gscreen.r.min.x/ws;
.
435,437c
				gscreen.ldepth, gscreen.r.min.x,
				gscreen.r.min.y, gscreen.r.max.x,
				gscreen.r.max.y);
.
417c
				q = (uchar*)gaddr(src, Pt(src->r.min.x, y));
.
335,339c
			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);
.
169c
	cursorback.ldepth = gscreen.ldepth;
.
167c
	if(gscreen.ldepth > 1)
.
148c
	bit.map[0] = gscreen;	/* bitmap 0 is screen */
.
47c
extern	GBitmap	gscreen;
.
9a
#include	<libg.h>
.
## diffname port/devbit.c 1990/1011
## diff -e /n/bootesdump/1990/0912/sys/src/9/68020/devbit.c /n/bootesdump/1990/1011/sys/src/9/68020/devbit.c
896a
			}else{
				GBitmap d;

				d = *dst;
				rect = rcanon(rect);
				if(rectclip(&d.r, rect)==0)
					return;
				/*
				 * Find x, maxx such that
				 * x <= rect.min.x < x+tw,
				 * maxx-tw < rect.max.x <= maxx
				 * and x, maxx are integral multiples of tw
				 * away from src->r.min.x
				 * Similarly for y, maxy
				 */
				if(x > rect.min.x)
					x -= ((x-rect.min.x+tw-1)/tw)*tw;
				else if(x+tw <= rect.min.x)
					x += ((rect.min.x-x)/tw)*tw;
				if(y > rect.min.y)
					y -= ((y-rect.min.y+th-1)/th)*th;
				else if(y+tw <= rect.min.y)
					y += ((rect.min.y-y)/th)*th;
				maxx = x+tw;
				if(maxx < rect.max.x)
					maxx += ((rect.max.x-maxx+tw-1)/tw)*tw;
				maxy = y+th;
				if(maxy < rect.max.y)
					maxy += ((rect.max.y-maxy+th-1)/th)*th;
				minx = x;
				if(off && !isoff){
					cursoroff(1);
					isoff = 1;
				}
				for( ; y<maxy; y+=th)
					for(x=minx; x<maxx; x+=tw)
						gbitblt(&d, Pt(x,y), src, src->r, v);
.
890,891c
				if(tw==16 && th==16)
					for(y=0; y<16; y++)
						t.bits[y] = src->base[y]>>16;
				else
					for(y=0; y<16; y++){
						l = src->base[y%(16/th)] >> (32-tw);
						for(i=16/tw, ws=l; i > 1; i--)
							ws = (ws<<tw) | l;
						t.bits[y] = ws;
					}
.
886,887c
			x = src->r.min.x;
			y = src->r.min.y;
			tw = src->r.max.x - x;
			th = src->r.max.y - y;
			if(x==0 && y==0 && 16%tw == 0 && 16%th == 0){
.
883,884d
473c
	long m, v, miny, maxy, minx, maxx, t, x, y, tw, th;
.
## diffname port/devbit.c 1990/1012
## diff -e /n/bootesdump/1990/1011/sys/src/9/68020/devbit.c /n/bootesdump/1990/1012/sys/src/9/68020/devbit.c
896c
						l = src->base[y%th] >> (32-tw);
.
## diffname port/devbit.c 1990/11211
## diff -e /n/bootesdump/1990/1012/sys/src/9/68020/devbit.c /n/bootesdump/1990/11211/sys/src/9/68020/devbit.c
1049c
		error(Ebadbitmap);
.
1021,1032d
1004c
				error(Ebadblt);
.
982c
				error(Ebadblt);
.
969c
				error(Ebadblt);
.
962c
				error(Ebadbitmap);
.
958c
				error(Ebadblt);
.
882c
				error(Ebadbitmap);
.
871c
				error(Ebadbitmap);
.
867c
				error(Ebadblt);
.
846c
				error(Ebadblt);
.
840c
				error(Ebadblt);
.
831c
				error(Ebadbitmap);
.
827c
				error(Ebadblt);
.
808c
				error(Ebadblt);
.
804c
				error(Ebadbitmap);
.
800c
				error(Ebadblt);
.
774c
				error(Ebadbitmap);
.
770c
				error(Ebadblt);
.
740c
				error(Ebadbitmap);
.
736c
				error(Ebadblt);
.
706c
				error(Ebadbitmap);
.
697c
			error(Enofont);
.
693c
				error(Ebadblt);
.
690c
				error(Ebadblt);
.
661c
				error(Ebadfont);
.
657c
				error(Ebadblt);
.
644c
				error(Ebadbitmap);
.
640c
				error(Ebadblt);
.
619c
				error(Ebadblt);
.
582c
				error(Ebadbitmap);
.
573c
				error(Ebadbitmap);
.
569c
				error(Ebadblt);
.
534c
					error(Enobitstore);
.
518c
				error(Enobitmap);
.
515c
				error(Ebadblt);
.
512c
				error(Ebadblt);
.
501c
			error(Ebadblt);
.
486,487c
	if(c->qid.path != Qbitblt)
		error(Egreg);
.
483,484c
	if(c->qid.path == CHDIR)
		error(Eisdir);
.
462c
		error(Egreg);
.
434c
				error(Eio);
.
429c
		error(Ebadblt);
.
412c
				error(Ebadblt);
.
401c
				error(Ebadblt);
.
394c
				error(Ebadbitmap);
.
380c
				error(Ebadblt);
.
366c
				error(Ebadblt);
.
334c
				error(Ebadblt);
.
299c
			error(Ebadblt);
.
290c
	switch(c->qid.path){
.
287c
	if(c->qid.path & CHDIR)
.
252c
	if(c->qid.path!=CHDIR && (c->flag&COPEN)){
.
242c
	error(Eperm);
.
236c
	error(Eperm);
.
230c
	error(Eperm);
.
210c
			error(Einuse);
.
205,206c
			error(Eperm);
	}else if(c->qid.path == Qbitblt){
.
203c
	if(c->qid.path == CHDIR){
.
184c
	if(c->qid.path != CHDIR)
.
128,130c
	"bitblt",	{Qbitblt},	0,			0600,
	"mouse",	{Qmouse},	0,			0600,
	"screen",	{Qscreen},	0,			0400,
.
## diffname port/devbit.c 1990/1219
## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devbit.c /n/bootesdump/1990/1219/sys/src/9/68020/devbit.c
594c
			balubitblt(dst, pt, src, rect, v);
.
## diffname port/devbit.c 1991/0318
## diff -e /n/bootesdump/1991/0201/sys/src/9/68020/devbit.c /n/bootesdump/1991/0318/sys/src/9/gnot/devbit.c
1070c
	memmove(&cursor, c, sizeof(Cursor));
.
1054c
			memmove(p1, p2, (2+p2[0])*sizeof(ulong));
.
622,623c
			memmove(curs.clr, p+9, 2*16);
			memmove(curs.set, p+41, 2*16);
.
## diffname port/devbit.c 1991/0329
## diff -e /n/bootesdump/1991/0318/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0329/sys/src/9/gnot/devbit.c
1060a
	if(p1<bit.words || p1>=bit.words+bit.nwords)
		panic("bitcompact");
.
## diffname port/devbit.c 1991/0411
## diff -e /n/bootesdump/1991/0329/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0411/sys/src/9/gnot/devbit.c
470c
bitwrite(Chan *c, void *va, long n, ulong offset)
.
444c
		t = offset-5*12;
.
432c
		if(offset==0){
.
278c
bitread(Chan *c, void *va, long n, ulong offset)
.
## diffname port/devbit.c 1991/0419
## diff -e /n/bootesdump/1991/0411/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0419/sys/src/9/gnot/devbit.c
193a
Chan*
bitclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

.
## diffname port/devbit.c 1991/0423
## diff -e /n/bootesdump/1991/0419/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0423/sys/src/9/gnot/devbit.c
1133,1151c

	if(dolock && !canlock(&cursor))
		return;

	x = mouse.xy.x + mouse.dx;
	if(x < gscreen.r.min.x)
		x = gscreen.r.min.x;
	if(x >= gscreen.r.max.x)
		x = gscreen.r.max.x;
	y = mouse.xy.y + mouse.dy;
	if(y < gscreen.r.min.y)
		y = gscreen.r.min.y;
	if(y >= gscreen.r.max.y)
		y = gscreen.r.max.y;
	cursoroff(0);
	mouse.xy = Pt(x, y);
	cursoron(0);
	mouse.dx = 0;
	mouse.dy = 0;
	mouse.clock = 0;
	mouse.track = 0;
	mouse.buttons = mouse.newbuttons;
	mouse.changed = 1;

	if(dolock){
.
1131a
	++mouse.clock;
}

void
mousetry(Ureg *ur)
{
	int s;

	if(mouse.clock && mouse.track && (ur->sr&SPL(7)) == 0 && canlock(&cursor)){
		s = spl1();
		mouseupdate(0);
		splx(s);
		unlock(&cursor);
		wakeup(&mouse.r);
	}
}

void
mouseupdate(int dolock)
{
.
528a
			if(Dx(rect) < 0 || Dy(rect) < 0)
				error(Ebadblt);
.
56a
	int	clock;		/* check mouse.track on RTE */
.
47a
void	mouseupdate(int);
.
8a
#include	"ureg.h"
.
## diffname port/devbit.c 1991/0427
## diff -e /n/bootesdump/1991/0423/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0427/sys/src/9/gnot/devbit.c
197,202d
## diffname port/devbit.c 1991/0605
## diff -e /n/bootesdump/1991/0427/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0605/sys/src/9/gnot/devbit.c
1147a
int
mouseputc(IOQ *q, int c)
{
	/*
	 *  put your favorite serial mouse code here
	 */
}

.
## diffname port/devbit.c 1991/0614
## diff -e /n/bootesdump/1991/0605/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0614/sys/src/9/gnot/devbit.c
1019a
	poperror();
.
## diffname port/devbit.c 1991/0619
## diff -e /n/bootesdump/1991/0614/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0619/sys/src/9/gnot/devbit.c
1012,1014c
			if(!eqpt(mouse.xy, pt1)){
				mouse.xy = pt1;
				mouse.track = 1;
				mouseclock();
			}
.
## diffname port/devbit.c 1991/0701
## diff -e /n/bootesdump/1991/0619/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0701/sys/src/9/gnot/devbit.c
948a
			gtexture(dst, rect, src, v);
.
889,947c
			if(off && !isoff){
				cursoroff(1);
				isoff = 1;
.
## diffname port/devbit.c 1991/0706
## diff -e /n/bootesdump/1991/0707/sys/src/9/gnot/devbit.c /n/bootesdump/1991/0706/sys/src/9/port/devbit.c
1104,1134c
	if((c&0xF0) == 0x80)
		nb=0;
	msg[nb] = c;
	if(c & 0x80)
		msg[nb] |= 0xFF00;	/* sign extend */
	if(++nb == 5){
		mouse.newbuttons = b[(msg[0]&7)^7];
		mouse.dx = msg[1]+msg[3];
		mouse.dy = -(msg[2]+msg[4]);
		mouse.track = 1;
		mouseclock();
		nb = 0;
.
1099,1102c
	static short msg[5];
	static int nb;
	static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7};
.
1079,1090c
	int x, y;
	if(mouse.track && canlock(&cursor)){
		x = mouse.xy.x + mouse.dx;
		if(x < gscreen.r.min.x)
			x = gscreen.r.min.x;
		if(x >= gscreen.r.max.x)
			x = gscreen.r.max.x;
		y = mouse.xy.y + mouse.dy;
		if(y < gscreen.r.min.y)
			y = gscreen.r.min.y;
		if(y >= gscreen.r.max.y)
			y = gscreen.r.max.y;
		cursoroff(0);
		mouse.xy = Pt(x, y);
		cursoron(0);
		mouse.dx = 0;
		mouse.dy = 0;
		mouse.track = 0;
		mouse.buttons = mouse.newbuttons;
		mouse.changed = 1;
.
1077c
mouseclock(void)	/* called splhi */
.
1065a
	mouse.dx += dx;
	mouse.dy += dy;
	mouse.newbuttons = b;
	mouse.track = 1;
}

void
mousebuttons(int b)	/* called at higher priority */
{
.
1064c
mousedelta(int b, int dx, int dy)	/* called at higher priority */
.
1046c
			&set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D);
.
1044c
			&clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S);
.
1014,1015d
964a

		case 'z':
			/*
			 * write the colormap
			 *
			 *	'z'		1
			 *	id		2
			 *	map		12*(2**bitmapdepth)
			 */
			if(m < 3)
				error(Ebadblt);
			v = GSHORT(p+1);
			if(v != 0)
				error(Ebadbitmap);
			m -= 3;
			p += 3;
			nw = 1 << (1 << bit.map[v].ldepth);
			if(m < 12*nw)
				error(Ebadblt);
			ok = 1;
			for(i = 0; i < nw; i++){
				ok &= setcolor(i, GLONG(p), GLONG(p+4), GLONG(p+8));
				p += 12;
				m -= 12;
			}
			if(!ok){
				/* assume monochrome: possibly change flipping */
				l = GLONG(p-12);
				getcolor(nw-1, &rv, &rv, &rv);
				flipping = (l != rv);
			}
			break;
.
957c
/*			if(!eqpt(mouse.xy, pt1))*/{
.
940,941c
				if(v == 0 && flipping)	/* flip bits */
					for(x=0; x<l; x++)
						*q++ = ~U2K(*p++);
				else
					for(x=0; x<l; x++)
						*q++ = U2K(*p++);
.
893c
			gtexture(dst, rect, src, fc);
.
888d
879a
			}
.
878c
			fc = GSHORT(p+21) & 0xF;
			if(v == 0){
				if(flipping)
					fc = flipD[fc];
.
856c
			gstring(dst, pt, f, (char*)p, fc);
.
846d
839a
			}
.
838c
			fc = GSHORT(p+13) & 0xF;
			if(v == 0){
				if(flipping)
					fc = flipD[fc];
.
791c
			gpoint(dst, pt1, t, fc);
.
786d
782a
			}
.
781c
			fc = GSHORT(p+12) & 0xF;
			if(v == 0){
				if(flipping)
					fc = flipD[fc];
.
763a
		case 'm':
			/*
			 * read colormap
			 *
			 *	'm'		1
			 *	id		2
			 */
			if(m < 3)
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(Ebadbitmap);
			bit.mid = v;
			m -= 3;
			p += 3;
			break;

.
759c
			gsegment(dst, pt1, pt2, t, fc);
.
754d
748a
			}
.
747c
			fc = GSHORT(p+20) & 0xF;
			if(v == 0){
				if(flipping)
					fc = flipD[fc];
.
599c
			gbitblt(dst, pt, src, rect, fc);
.
594d
584,589d
581a
			}
.
579,580c
			if(v == 0){
				if(flipping)
					fc = flipD[fc];
.
574a
			fc = GSHORT(p+29) & 0xF;
			v = GSHORT(p+11);
			src = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || src->ldepth < 0)
				error(Ebadbitmap);
			off = 0;
			if(v == 0){
				if(flipping)
					fc = flipS[fc];
				off = 1;
			}
.
517c
			if(v>3)	/* BUG */
.
481a
	Fcode fc;
.
476,478c
	long m, v, miny, maxy, minx, maxx, t, x, y;
	ulong l, nw, ws, rv;
	int off, isoff, i, ok;
.
423,424c
				if(bit.rid == 0 && flipping)	/* flip bits */
					for(x=0; x<l; x++)
						*p++ = ~K2U(*q++);
				else
					for(x=0; x<l; x++)
						*p++ = K2U(*q++);
.
392c
			 * read bitmap:
.
389a
		if(bit.mid >= 0){
			/*
			 * read colormap:
			 *	data		12*(2**bitmapdepth)
			 */
			l = (1<<bit.map[bit.mid].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;
			break;
		}
.
285c
	ulong l, nw, ws, rv, gv, bv;
.
275c
 * bit order. So far all machines have the same (good) order; when
 * that changes, these should switch on a variable set at init time.
.
217a
		bit.mid = -1;
.
188a
	return nc;
.
171,173c
	if(gscreen.ldepth > 3)
		cursorback.ldepth = 0;
	else {
		cursorback.ldepth = gscreen.ldepth;
		cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5;
	}
.
152a
	getcolor(0, &r, &r, &r);
	if(r == 0)
		flipping = 1;
.
143a
	ulong r;
.
108c
ulong cursorbackbits[16*4];
.
63a
	int	newbuttons;	/* interrupt time access only */
.
62d
59d
54c
	 * First four fields are known in screen.c
.
49d
43a
	int	mid;		/* colormap read bitmap id */
.
16a
 * Some monochrome screens are reversed from what we like:
 * We want 0's bright and 1s dark.
 * Indexed by an Fcode, these compensate for the source bitmap being wrong
 * (exchange S rows) and destination (exchange D columns and invert result)
 */
int flipS[] = {
	0x0, 0x4, 0x8, 0xC, 0x1, 0x5, 0x9, 0xD,
	0x2, 0x6, 0xA, 0xE, 0x3, 0x7, 0xB, 0xF
};

int flipD[] = {
	0xF, 0xD, 0xE, 0xC, 0x7, 0x5, 0x6, 0x4,
	0xB, 0x9, 0xA, 0x8, 0x3, 0x1, 0x2, 0x0, 
};

int flipping;	/* are flip tables being used to transform Fcodes? */
int hwcursor;	/* is there a hardware cursor? */

/*
.
9d
## diffname port/devbit.c 1991/0707
## diff -e /n/bootesdump/1991/0706/sys/src/9/port/devbit.c /n/bootesdump/1991/0707/sys/src/9/port/devbit.c
1218,1236c

	if(!mouse.track || (dolock && !canlock(&cursor)))
		return;

	x = mouse.xy.x + mouse.dx;
	if(x < gscreen.r.min.x)
		x = gscreen.r.min.x;
	if(x >= gscreen.r.max.x)
		x = gscreen.r.max.x;
	y = mouse.xy.y + mouse.dy;
	if(y < gscreen.r.min.y)
		y = gscreen.r.min.y;
	if(y >= gscreen.r.max.y)
		y = gscreen.r.max.y;
	cursoroff(0);
	mouse.xy = Pt(x, y);
	cursoron(0);
	mouse.dx = 0;
	mouse.dy = 0;
	mouse.clock = 0;
	mouse.track = 0;
	mouse.buttons = mouse.newbuttons;
	mouse.changed = 1;

	if(dolock){
.
1215c
mouseupdate(int dolock)
.
1213a

.
98,104d
70,81c
Mouseinfo	mouse;
Cursorinfo	cursor;
.
11a
#include	"mouse.h"
.
## diffname port/devbit.c 1991/0708
## diff -e /n/bootesdump/1991/0707/sys/src/9/port/devbit.c /n/bootesdump/1991/0708/sys/src/9/port/devbit.c
12c
#include	"screen.h"
.
## diffname port/devbit.c 1991/0710
## diff -e /n/bootesdump/1991/0708/sys/src/9/port/devbit.c /n/bootesdump/1991/0710/sys/src/9/port/devbit.c
1171c
		kbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
.
1158c
		kbitblt(&gscreen, add(mouse.xy, cursor.offset),
.
1155,1156c
		kbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S);
		kbitblt(&gscreen, add(mouse.xy, cursor.offset),
.
648c
			ubitblt(dst, pt, src, rect, fc);
.
## diffname port/devbit.c 1991/0731
## diff -e /n/bootesdump/1991/0710/sys/src/9/port/devbit.c /n/bootesdump/1991/0731/sys/src/9/port/devbit.c
1140,1141c
		p = (uchar*)&setbits[i];
		*p = c->set[2*i];
		*(p+1) = c->set[2*i+1];
		p = (uchar*)&clrbits[i];
		*p = c->clr[2*i];
		*(p+1) = c->clr[2*i+1];
.
1135a
	uchar *p;
.
## diffname port/devbit.c 1991/1023
## diff -e /n/bootesdump/1991/0731/sys/src/9/port/devbit.c /n/bootesdump/1991/1023/sys/src/9/port/devbit.c
490c
		miny = t/l;	/* unsigned computation */
.
## diffname port/devbit.c 1991/1105
## diff -e /n/bootesdump/1991/1023/sys/src/9/port/devbit.c /n/bootesdump/1991/1105/sys/src/9/port/devbit.c
500,501c
			if(flipping)
				for(x=0; x<l; x++)
					*p++ = ~K2U(*q++);
			else
				for(x=0; x<l; x++)
					*p++ = K2U(*q++);
.
## diffname port/devbit.c 1991/1112
## diff -e /n/bootesdump/1991/1105/sys/src/9/port/devbit.c /n/bootesdump/1991/1112/sys/src/9/port/devbit.c
132,134c
	"bitblt",	{Qbitblt},	0,			0666,
	"mouse",	{Qmouse},	0,			0666,
	"screen",	{Qscreen},	0,			0444,
.
## diffname port/devbit.c 1991/1115
## diff -e /n/bootesdump/1991/1112/sys/src/9/port/devbit.c /n/bootesdump/1991/1115/sys/src/9/port/devbit.c
1266a
	USED(m);
.
1248a
	USED(q);
.
254a
	USED(c, db);
.
248a
	USED(c);
.
242a
	USED(c, name, omode, perm);
.
## diffname port/devbit.c 1991/1225
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/devbit.c /n/bootesdump/1991/1225/sys/src/9/port/devbit.c
1183c
		gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
.
1170c
		gbitblt(&gscreen, add(mouse.xy, cursor.offset),
.
1167,1168c
		gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S);
		gbitblt(&gscreen, add(mouse.xy, cursor.offset),
.
655c
			gbitblt(dst, pt, src, rect, fc);
.
## diffname port/devbit.c 1992/0111
## diff -e /n/bootesdump/1991/1225/sys/src/9/port/devbit.c /n/bootesdump/1992/0111/sys/src/9/port/devbit.c
6c
#include	"../port/error.h"
.
## diffname port/devbit.c 1992/0208
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devbit.c /n/bootesdump/1992/0208/sys/src/9/port/devbit.c
939c
			gsubfstring(dst, pt, f, (char*)p, fc);
.
928c
			if(v<0 || v>=conf.nsubfont || f->bits==0 || f->bits->ldepth<0)
.
755c
			for(i=1; i<conf.nsubfont; i++)
.
721c
			if(v<0 || v>=conf.nsubfont || f->bits==0)
.
534c
	GSubfont *f;
.
274c
			for(i=1,fp=&bit.font[1]; i<conf.nsubfont; i++,fp++)
.
266c
	GSubfont *fp;
.
166c
	for(i=1; i<conf.nsubfont; i++)
.
164c
	bit.font = ialloc(conf.nsubfont * sizeof(GSubfont), 0);
.
56c
	GSubfont *font;		/* arena; looked up linearly BUG */
.
14c
extern GSubfont	*defont;
.
## diffname port/devbit.c 1992/0209
## diff -e /n/bootesdump/1992/0208/sys/src/9/port/devbit.c /n/bootesdump/1992/0209/sys/src/9/port/devbit.c
1106c
GBitmap*
.
1103a
void
bitstring(GBitmap *bp, Point pt, GFont *f, uchar *p, long l, Fcode fc)
{
	int full;
	Rectangle rect;
	ushort r;
	GCacheinfo *c;

	full = (fc==S || fc==notS);	/* for reverse-video */
	if(full){
		rect.min.y = 0;
		rect.max.y = f->height;
	}

	while(l > 0){
		r = GSHORT(p);
		if(r >= NFCACHE+NFLOOK)
			error(Ebadblt);
		p += 2;
		l -= 2;
		c = &f->cache[r];
		if(!full){
			rect.min.y = c->top;
			rect.max.y = c->bottom;
		}
		rect.min.x = c->x;
		rect.max.x = c->xright;
		gbitblt(bp, Pt(pt.x+c->left, pt.y+rect.min.y), f->b, rect, fc);
		pt.x += c->width;
	}
}

void
bitloadchar(GFont *f, int ci, GSubfont *subf, int si)
{
	GCacheinfo *c;
	Rectangle rect;
	Fontchar *fi;

	c = &f->cache[ci];
	fi = &subf->info[si];
	c->top = fi->top + (f->ascent-subf->ascent);
	c->bottom = fi->bottom + (f->ascent-subf->ascent);
	c->width = fi->width;
	c->left = fi->left;
	c->x = ci*f->width;
	c->xright = c->x + ((fi+1)->x - fi->x);
	rect.min.y = 0;
	rect.max.y = f->height;
	rect.min.x = c->x;
	rect.max.x = c->xright;
	gbitblt(f->b, Pt(c->x, 0), subf->bits, rect, 0);
	rect.min.x = fi->x;
	rect.max.x = (fi+1)->x;
	gbitblt(f->b, Pt(c->x, f->ascent-subf->ascent), subf->bits, rect, S);
}

.
1094a
GBitmap*
bitalloc(Rectangle rect, int ld)
{
	GBitmap *bp;
	ulong l, ws, nw;
	long t;

	if(bit.free == 0)
		error(Enobitmap);
	ws = 1<<(5-ld);	/* pixels per word */
	if(rect.min.x >= 0)
		l = (rect.max.x+ws-1)/ws - rect.min.x/ws;
	else{	/* make positive before divide */
		t = (-rect.min.x)+ws-1;
		t = (t/ws)*ws;
		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);
	}
	bp = bit.free;
	bit.free = (GBitmap*)(bp->base);
	*bit.wfree++ = nw;
	*bit.wfree++ = (ulong)bp;
	bp->base = bit.wfree;
	memset(bp->base, 0, nw*sizeof(ulong));
	bit.wfree += nw;
	bp->zero = l*rect.min.y;
	if(rect.min.x >= 0)
		bp->zero += rect.min.x/ws;
	else
		bp->zero -= (-rect.min.x+ws-1)/ws;
	bp->zero = -bp->zero;
	bp->width = l;
	bp->ldepth = ld;
	bp->r = rect;
	bp->cache = 0;
	return bp;
}

.
1055a
		case 'y':
			/*
			 * load font from subfont
			 *	'y'		1
			 *	id		2
			 *	cache pos	2
			 *	subfont id	2
			 *	subfont index	2
			 */
			if(m < 9)
				error(Ebadblt);
			v = GSHORT(p+1);
			ff = &bit.font[v];
			if(v<0 || v>=conf.nfont || ff->ldepth<0 || ff->b==0)
				error(Ebadblt);
			l = GSHORT(p+3);
			if(l >= NFCACHE+NFLOOK)
				error(Ebadblt);
			v = GSHORT(p+5);
			f = &bit.subfont[v];
			if(v<0 || v>=conf.nsubfont || f->bits->ldepth<0)
				error(Ebadblt);
			nw = GSHORT(p+7);
			if(nw >= f->n)
				error(Ebadblt);
			bitloadchar(ff, l, f, nw);
			p += 9;
			m -= 9;
			break;

.
1031c
						*q++ = *p++;
.
1028c
						*q++ = ~(*p++);
.
983a
		case 'u':
			/*
			 * string
			 *	'u'		1
			 *	id		2
			 *	pt		8
			 *	font id		2
			 *	code		2
			 *	n		2
			 * 	cache indexes	2*n (not null terminated)
			 */
			if(m < 17)
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(Ebadbitmap);
			off = 0;
			fc = GSHORT(p+13) & 0xF;
			if(v == 0){
				if(flipping)
					fc = flipD[fc];
				off = 1;
			}
			pt.x = GLONG(p+3);
			pt.y = GLONG(p+7);
			v = GSHORT(p+11);
			ff = &bit.font[v];
			if(v<0 || v>=conf.nfont || ff->ldepth<0)
				error(Ebadblt);
			l = GSHORT(p+15)*2;
			p += 17;
			m -= 17;
			if(l > m)
				error(Ebadblt);
			if(off && !isoff){
				cursoroff(1);
				isoff = 1;
			}
			bitstring(dst, pt, ff, p, l, fc);
			m -= l;
			p += l;
			break;

		case 'v':
			/*
			 * clear font cache and bitmap
			 *	'v'		1
			 *	id		2
			 *	width		2
			 */
			if(m < 5)
				error(Ebadblt);
			v = GSHORT(p+1);
			ff = &bit.font[v];
			if(v<0 || v>=conf.nfont || ff->ldepth<0)
				error(Ebadblt);
			/*
			 * memset not necessary but helps avoid
			 * confusion if the cache is mishandled by the
			 * user.
			 */
			memset(ff->cache, 0, (NFCACHE+NFLOOK)*sizeof(ff->cache[0]));
			if(ff->b)
				bitfree(ff->b);
			ff->width = GSHORT(p+3);
			ff->b = 0;
			ff->b = bitalloc(Rect(0, 0, (NFCACHE+NFLOOK)*ff->width, ff->height), ff->ldepth);
			p += 5;
			m -= 5;
			break;

.
927c
			f = &bit.subfont[v];
.
907c
			 *	subfont id	2
.
903c
			 * subfstring
.
840a
		case 'n':
			/*
			 * allocate font
			 *	'n'		1
			 *	height		1
			 *	ascent		1
			 *	ldepth		2
			 * next read returns allocated font id
			 */
			if(m < 5)
				error(Ebadblt);
			v = GSHORT(p+3);
			if(v < 0)
				error(Ebadblt);
			for(i=0; i<conf.nfont; i++)
				if(bit.font[i].ldepth < 0)
					goto fontfound;
			error(Enofont);
		fontfound:
			ff = &bit.font[i];
			ff->height = p[1];
			ff->ascent = p[2];
			ff->ldepth = v;
			ff->width = 0;
if(ff->b)print("font allocate: bitmap nonzero\n");
			ff->b = 0;
			m -= 5;
			p += 5;
			bit.lastfid = ff - bit.font;
			break;

.
781c
			bit.lastsubfid = f - bit.subfont;
.
759,760c
		subfontfound:
			f = &bit.subfont[i];
.
756,757c
				if(bit.subfont[i].bits == 0)
					goto subfontfound;
.
741c
			 * allocate subfont
.
727a
		case 'h':
			/*
			 * free font
			 *	'h'		1
			 *	id		2
			 */
			if(m < 3)
				error(Ebadblt);
			v = GSHORT(p+1);
			ff = &bit.font[v];
			if(v<0 || v>=conf.nfont || ff->ldepth<0)
				error(Ebadfont);
			if(ff->b)
				bitfree(ff->b);
			ff->b = 0;
			ff->ldepth = -1;
			m -= 3;
			p += 3;
			break;

.
720c
			f = &bit.subfont[v];
.
713c
			 * free subfont (free bitmap separately)
.
578,607c
			bp = bitalloc(rect, v);
.
569,571d
567c
			if(v > 3)	/* BUG */
.
534a
	GFont *ff;
.
508c
					*p++ = *q++;
.
505c
					*p++ = ~(*q++);
.
469c
						*p++ = *q++;
.
466c
						*p++ = ~(*q++);
.
398a
			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';
.
394c
			 *	subfont id	2
.
392c
			 * allocate subfont:
.
390c
		if(bit.lastsubfid > 0){
.
286,293d
275a
			for(i=0,ffp=&bit.font[0]; i<conf.nfont; i++,ffp++){
				ffp->b = 0;
				ffp->ldepth = -1;
			}
bit.font[0].ldepth=0;/*BUG */
.
274c
			for(i=1,fp=&bit.subfont[1]; i<conf.nsubfont; i++,fp++)
.
266a
	GFont *ffp;
.
225a
		bit.lastsubfid = -1;
.
167c
		bit.subfont[i].info = ialloc((NINFO+1)*sizeof(Fontchar), 0);
	for(i=0; i<conf.nfont; i++)
		bit.font[i].ldepth = -1;
.
164,165c
	bit.subfont = ialloc(conf.nsubfont * sizeof(GSubfont), 0);
	bit.subfont[0] = *defont;
	bit.font = ialloc(conf.nfont * sizeof(GFont), 0);
.
159a
	bit.lastsubfid = -1;
.
68a
void	bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode);
void	bitloadchar(GFont*, int, GSubfont*, int);
.
67a
GBitmap*bitalloc(Rectangle, int);
.
57a
	int	lastsubfid;	/* last allocated subfont id */
.
56c
	GFont *font;		/* arena; looked up linearly BUG */
	GSubfont *subfont;	/* arena; looked up linearly BUG */
.
33d
18c
 * We want 0's bright and 1's dark.
.
10c
#include	<libng.h>
.
## diffname port/devbit.c 1992/0210
## diff -e /n/bootesdump/1992/0209/sys/src/9/port/devbit.c /n/bootesdump/1992/0210/sys/src/9/port/devbit.c
875d
## diffname port/devbit.c 1992/0211
## diff -e /n/bootesdump/1992/0210/sys/src/9/port/devbit.c /n/bootesdump/1992/0211/sys/src/9/port/devbit.c
1308a
		if(r >= NFCACHE+NFLOOK)
			continue;
.
1305,1306d
10c
#include	<libg.h>
.
## diffname port/devbit.c 1992/0212
## diff -e /n/bootesdump/1992/0211/sys/src/9/port/devbit.c /n/bootesdump/1992/0212/sys/src/9/port/devbit.c
1173c
			 *	cache index	2
.
## diffname port/devbit.c 1992/0214
## diff -e /n/bootesdump/1992/0212/sys/src/9/port/devbit.c /n/bootesdump/1992/0214/sys/src/9/port/devbit.c
1339,1340c
	rect.max.x = c->x+f->width;
	gbitblt(f->b, rect.min, f->b, rect, 0);
.
## diffname port/devbit.c 1992/0219
## diff -e /n/bootesdump/1992/0214/sys/src/9/port/devbit.c /n/bootesdump/1992/0219/sys/src/9/port/devbit.c
1343a
/*
gbitblt(&gscreen, Pt(0,0), f->b, f->b->r, S);
gbitblt(&gscreen, Pt(0,30), f->b, Rect(c->x, 0, c->x+f->width,f->height), S);
*/
.
1342a
	rect.max.y = subf->height;
.
1330,1331c
	/* careful about sign extension: top and bottom are uchars */
	y = fi->top + (f->ascent-subf->ascent);
	if(y < 0)
		y = 0;
	c->top = y;
	y = fi->bottom + (f->ascent-subf->ascent);
	if(y < 0)
		y = 0;
	c->bottom = y;
.
1326a
	int y;
.
## diffname port/devbit.c 1992/0321
## diff -e /n/bootesdump/1992/0219/sys/src/9/port/devbit.c /n/bootesdump/1992/0321/sys/src/9/port/devbit.c
2c
#include	"../port/lib.h"
.
## diffname port/devbit.c 1992/0519
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devbit.c /n/bootesdump/1992/0519/sys/src/9/port/devbit.c
1247,1248c
	if(rect.min.x >= 0) {
		l = (rect.max.x+ws-1)/ws;
		l -= rect.min.x/ws;
	}
.
## diffname port/devbit.c 1992/0522
## diff -e /n/bootesdump/1992/0519/sys/src/9/port/devbit.c /n/bootesdump/1992/0522/sys/src/9/port/devbit.c
1522a
	return 0;
.
## diffname port/devbit.c 1992/0604
## diff -e /n/bootesdump/1992/0522/sys/src/9/port/devbit.c /n/bootesdump/1992/0604/sys/src/9/port/devbit.c
1355,1358d
1277a
	bp->clipr = rect;
.
990c
			 *	rect		16
.
915a
		case 'q':
			/*
			 * clip rectangle
			 *	'q'		1
			 *	id		2
			 *	rect		16
			 */
			if(m < 19)
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(Ebadbitmap);
			rect.min.x = GLONG(p+3);
			rect.min.y = GLONG(p+7);
			rect.max.x = GLONG(p+11);
			rect.max.y = GLONG(p+15);
			if(rectclip(&rect, dst->r))
				dst->clipr = rect;
			else
				dst->clipr = dst->r;
			m -= 19;
			p += 19;
			break;

.
231a
		bit.map[0].clipr = gscreen.clipr;
.
195a
	bit.map[0] = gscreen;	/* bitmap 0 is screen */
.
119a
	{0, 0, 16, 16},
.
109a
	{0, 0, 16, 16},
.
99a
	{0, 0, 16, 16},
.
## diffname port/devbit.c 1992/0605
## diff -e /n/bootesdump/1992/0604/sys/src/9/port/devbit.c /n/bootesdump/1992/0605/sys/src/9/port/devbit.c
749c
			bit.init = *p;
.
747c
			 *	'i','j'		1
.
743a
		case 'j':
.
384c
				n = dn;
.
382c
				n = dn+3*12+6*(defont->n+1);
.
370,371c
			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;
.
312c
	int off, j, dn;
.
## diffname port/devbit.c 1992/0621
## diff -e /n/bootesdump/1992/0605/sys/src/9/port/devbit.c /n/bootesdump/1992/0621/sys/src/9/port/devbit.c
1398,1407d
1331a
fontfree(GFont *f)
{
	if(f->b)
		bitfree(f->b);
	free(f);
}

void
subfontfree(GSubfont *s)
{
	free(s->info);
	free(s);
}

void
.
1325,1328c
	b->base[-1] = 0;
	free(b);
.
1323c
bitfree(GBitmap *b)
.
1312,1319c
		b->zero -= (-rect.min.x+ws-1)/ws;
	b->zero = -b->zero;
	b->width = l;
	b->ldepth = ld;
	b->r = rect;
	b->clipr = rect;
	b->cache = 0;
	/* worth doing better than linear lookup? */
	ep = bit.map+bit.nmap;
	for(bp=bit.map; bp<ep; bp++)
		if(*bp == 0)
			break;
	if(bp == ep){
		bp = bit.map;
		bit.map = smalloc((bit.nmap+DMAP)*sizeof(GBitmap*));
		memmove(bit.map, bp, bit.nmap*sizeof(GBitmap*));
		free(bp);
		bp = bit.map+bit.nmap;
		bit.nmap += DMAP;
	}
	*bp = b;
	return bp-bit.map;
.
1310c
		b->zero += rect.min.x/ws;
.
1308c
	b->zero = l*rect.min.y;
.
1304,1306c
	*bit.wfree++ = (ulong)b;
	b->base = bit.wfree;
	memset(b->base, 0, nw*sizeof(ulong));
.
1301,1302c
	b = smalloc(sizeof(GBitmap));
.
1289,1290c
	}else{	/* make positive before divide */
.
1286c
	if(rect.min.x >= 0){
.
1283,1284c
print("bitalloc %lux\n", bit.wfree);
.
1281a
	int i;
.
1279c
	GBitmap *b, **bp, **ep;
.
1276c
int
.
1252c
			nw = 1 << (1 << gscreen.ldepth);
.
1226,1227c
			if(v<0 || v>=conf.nsubfont || (f=bit.subfont[v])==0)
.
1219,1220c
			if(v<0 || v>=conf.nfont || (ff=bit.font[v])==0)
.
1147,1148c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
1130c
			i = bitalloc(Rect(0, 0, (NFCACHE+NFLOOK)*ff->width, ff->height), ff->ldepth);
			ff->b = bit.map[i];
			bit.map[i] = 0;	/* disconnect it from GBitmap space */
.
1117,1118c
			if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
.
1090,1091c
			if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
.
1077,1078c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
1051,1052c
			if(v<0 || v>=bit.nmap || (src=bit.map[v])==0)
.
1036,1037c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
1006,1007c
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0)
.
993,994c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
966,967c
			if(v<0 || v>=bit.nmap || (src=bit.map[v])==0)
.
940,941c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
908,909c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
892c
			bit.lastfid = i;
.
884c
			ff = smalloc(sizeof(GFont));
			bit.font[i] = ff;
			ff = bit.font[i];
.
882c
			ffp = bit.font;
			bit.font = smalloc((bit.nfont+DMAP)*sizeof(GFont*));
			memmove(bit.font, ffp, bit.nfont*sizeof(GFont*));
			free(ffp);
			bit.nfont += DMAP;
.
879,880c
			for(i=0; i<bit.nfont; i++)
				if(bit.font[i] == 0)
.
857,858c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
823,824c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
805c
			bit.lastsubfid = i;
.
795c
			for(j=0; j<=f->n; j++,fcp++){
.
789,790c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
784c
			f = smalloc(sizeof(GSubfont));
			bit.subfont[i] = f;
			f->info = smalloc((v+1)*sizeof(Fontchar));
.
782c
			fp = bit.subfont;
			bit.subfont = smalloc((bit.nsubfont+DMAP)*sizeof(GSubfont*));
			memmove(bit.subfont, fp, bit.nsubfont*sizeof(GSubfont*));
			free(fp);
			bit.nsubfont += DMAP;
.
779,780c
			for(i=1; i<bit.nsubfont; i++)
				if(bit.subfont[i] == 0)
.
743,746c
			fontfree(ff);
			bit.font[v] = 0;
.
740,741c
			if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
.
726c
			subfontfree(f);
			bit.subfont[v] = 0;
.
723,724c
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0)
.
709a
			bit.map[v] = 0;
.
706,707c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
640,641c
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
.
630,631c
			if(v<0 || v>=bit.nmap || (src=bit.map[v])==0)
.
610,611c
			bit.lastid = bitalloc(rect, v);
.
584a
	SET(src, dst, f, ff);
.
567,569c
	GBitmap *b, *src, *dst, *bp;
	GSubfont *f, **fp;
	GFont *ff, **ffp;
.
561c
	int off, isoff, i, j, ok;
.
470,471c
			src = bit.map[bit.rid];
			if(src == 0)
.
443c
			src = bit.map[bit.mid];
			if(src == 0)
				error(Ebadbitmap);
			l = (1<<src->ldepth);
.
295c
			/* 0th subfont, defont, points to real storage */
			esp = &bit.subfont[bit.nsubfont];
			for(sp=&bit.subfont[1]; sp<esp; sp++){
				s = *sp;
				if(s){
					subfontfree(s);
					*sp = 0;
				}
			}
			efp = &bit.font[bit.nfont];
			for(fp=bit.font; fp<efp; fp++){
				f = *fp;
				if(f){
					fontfree(f);
					*fp = 0;
				}
			}
.
286,293c
			/* 0th bitmap, screen, has no special storage */
			bp = bit.map;
			free(*bp);
			*bp = 0;
			ebp = &bit.map[bit.nmap];
			bp++;
			for(; bp<ebp; bp++){
				b = *bp;
				if(b){
					bitfree(b);
					*bp = 0;
				}
.
278,281c
	GBitmap *b, **bp, **ebp;
	GSubfont *s, **sp, **esp;
	GFont *f, **fp, **efp;
.
236c
		b = smalloc(sizeof(GBitmap));
		*b = gscreen;
		bit.map[0] = b;			/* bitmap 0 is screen */
		bit.subfont[0] = defont;	/* subfont 0 is default */
.
226a
	GBitmap *b;

.
224c
Chan*
.
199d
189c
	else{
.
172,178c
	bit.font = smalloc(DMAP*sizeof(GFont*));
	bit.nfont = DMAP;
	bit.subfont = smalloc(DMAP*sizeof(GSubfont*));
	bit.nsubfont = DMAP;
.
169a
print("bitreset %lux\n", bit.words);
.
165d
154,161c
	bit.map = smalloc(DMAP*sizeof(GBitmap*));
	bit.nmap = DMAP;
.
145c
#define	NINFO	8192
.
70a
void	fontfree(GFont*);
void	subfontfree(GSubfont*);
.
69c
int	bitalloc(Rectangle, int);
.
66a
#define	DMAP	32		/* delta increase in size of arrays */
.
55,56c
	GFont	**font;		/* indexed array */
	int	nfont;		/* number allocated */
	GSubfont**subfont;	/* indexed array */
	int	nsubfont;	/* number allocated */
.
50,51c
	GBitmap	**map;		/* indexed array */
	int	nmap;		/* number allocated */
.
44c
 * followed by N blocks.  The bitmap pointer is zero if block is free.
 * 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
 * fonts are handled similarly.
.
40,42d
## diffname port/devbit.c 1992/0622
## diff -e /n/bootesdump/1992/0621/sys/src/9/port/devbit.c /n/bootesdump/1992/0622/sys/src/9/port/devbit.c
1459,1460c
	for(a=bit.arena; a<ea && a->words; a++)
		if(a->nbusy == 0)
			arenafree(a);
.
1456,1457c
		a->wfree = p1;
.
1452,1454c
		/* 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++;
.
1450a
		/* 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;
.
1445,1449c
	ea = &bit.arena[bit.narena];
	for(a=bit.arena; a<ea; a++){
		if(a->words == 0)
.
1443c
	Arena *a, *b, *ea, *na;
	ulong *p1, *p2, n;
.
1438,1439d
1372a
arenafree(Arena *a)
{
	xfree(a->words);
	a->words = 0;
}

void
.
1352a
	Arena *a;

	a = (Arena*)(b->base[-2]);
	a->nbusy--;
	if(a->nbusy == 0)
		arenafree(a);
.
1321c
	a->wfree += nw;
	a->nbusy++;
.
1317,1319c
	*a->wfree++ = nw;
	*a->wfree++ = (ulong)a;
	*a->wfree++ = (ulong)b;
	b->base = a->wfree;
.
1315a

	/* 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:
.
1311,1314c
	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;
.
1300d
1298c
	int i, try;
.
1294a
	Arena *a, *ea, *na, *aa;
.
1288a
	qunlock(&bit);
.
1243c
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0)
.
1237c
			if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
.
1004,1045d
601a
		qunlock(&bit);
.
600a
	qlock(&bit);
.
573a
	poperror();
	qunlock(&bit);
.
572a
	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;
	}
.
571a

	qlock(&bit);
	if(waserror()){
		qunlock(&bit);
		nexterror();
.
568,570c
		return n;
	}
	if(c->qid.path != Qbitblt)
.
544,545c
			return 5*12;
.
364,536c
		return 10;
	}
	if(c->qid.path == Qscreen){
.
339,340c
	if(c->qid.path == Qmouse){
.
175a
	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 */
.
168,171d
158a
	Arena *a;
.
151a
#define	HDR	3
.
76a
void	arenafree(Arena*);
.
71a

.
70c
#define	DMAP	16		/* delta increase in size of arrays */
.
59a
	Arena	*arena;		/* array */
	int	narena;		/* number allocated */
.
53,55d
50a
	QLock;
.
47a
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 */
};

.
40,41c
 * 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.
.
## diffname port/devbit.c 1992/0627
## diff -e /n/bootesdump/1992/0622/sys/src/9/port/devbit.c /n/bootesdump/1992/0627/sys/src/9/port/devbit.c
1382a
	free(f->cache);
.
1097a
		case 't':
			/*
			 * texture
			 *	't'		1
			 *	dst id		2
			 *	rect		16
			 *	src id		2
			 *	fcode		2
			 */
			if(m < 23)
				error(Ebadblt);
			v = GSHORT(p+1);
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
				error(Ebadbitmap);
			off = 0;
			fc = GSHORT(p+21) & 0xF;
			if(v == 0){
				if(flipping)
					fc = flipD[fc];
				off = 1;
			}
			rect.min.x = GLONG(p+3);
			rect.min.y = GLONG(p+7);
			rect.max.x = GLONG(p+11);
			rect.max.y = GLONG(p+15);
			v = GSHORT(p+19);
			if(v<0 || v>=bit.nmap || (src=bit.map[v])==0)
				error(Ebadbitmap);
			if(off && !isoff){
				cursoroff(1);
				isoff = 1;
			}
			gtexture(dst, rect, src, fc);
			m -= 23;
			p += 23;
			break;

.
1065c
			 * 	cache indices	2*n (not null terminated)
.
1059c
			 *	's'		1
.
1021,1057d
1019c
		case 's':
.
932,933c
			m -= 7;
			p += 7;
.
924a
			ff->ncache = t;
			ff->cache = smalloc(t*sizeof(GCacheinfo));
.
913c
			t = GSHORT(p+5);
			if(v<0 || t<0)
.
910c
			if(m < 7)
.
907a
			 *	ncache		2
.
791c
			bit.init = 1;
.
789c
			 *	'i'		1
.
785d
473c
			n = 34;
.
471c
			n = 34+3*12+6*(defont->n+1);
.
451,460c
		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);
		if(n >= 34+3*12+6*(defont->n+1)){
			p += 34;
.
443c
		if(n < 34)
.
439c
		 * 	clip rectangle	16
.
355c
	int off, j;
.
## diffname port/devbit.c 1992/06271
## diff -e /n/bootesdump/1992/0627/sys/src/9/port/devbit.c /n/bootesdump/1992/06271/sys/src/9/port/devbit.c
1388a
	bitfree(s->bits);
.
1387c
subfontfree(BSubfont *s)
.
1122,1123c
			p += 7;
			m -= 7;
.
1119c
			i = bitalloc(Rect(0, 0, t*ff->width, ff->height), ff->ldepth);
.
1117c
			ff->width = GSHORT(p+5);
.
1114c
			if(t == ff->ncache)
				memset(ff->cache, 0, t*sizeof(ff->cache[0]));
			else{
				free(ff->cache);
				ff->cache = smalloc(t*sizeof(ff->cache[0]));
				ff->ncache = t;
			}
.
1107c
			t = GSHORT(p+3);
			if(t<0 || v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
.
1104c
			if(m < 7)
.
1101a
			 *	ncache		2
.
839d
825,826c
			f->bits = dst;
			bit.map[v] = 0;	/* subfont now owns bitmap */
			m -= 15;
			p += 15;
.
821a
			f->qid[0] = GLONG(p+7);
			f->qid[1] = GLONG(p+11);
.
816c
			f = smalloc(sizeof(BSubfont));
.
811,812c
			bit.subfont = smalloc((bit.nsubfont+DMAP)*sizeof(BSubfont*));
			memmove(bit.subfont, fp, bit.nsubfont*sizeof(BSubfont*));
.
805c
			if(v<0 || v>NINFO || m<15+6*(v+1))
.
802c
			if(m < 15)
.
798a
			 *	qid		8
.
790a
		case 'j':
			/*
			 * font cache check
			 *
			 *	'j'		1
			 *	qid		8	BUG: ignored
			 */
			m -= 9;
			p += 9;
			error(Esfnotcached);	/* BUG */
			break;

.
600c
	BSubfont *f, **fp;
.
386c
		return 14;
.
383a
		PLONG(p+10, TK2MS(MACHP(0)->ticks));
.
369c
		if(n < 14)
.
367a
		 * 	msec		4
.
311c
			if(*bp)
				free(*bp);
.
303c
	BSubfont *s, **sp, **esp;
.
260c
		bit.subfont[0] = (BSubfont*)defont;	/* subfont 0 is default */
		bit.subfont[0]->ref = 1;
		bit.subfont[0]->qid[0] = 0;
		bit.subfont[0]->qid[1] = 0;
.
184c
	bit.subfont = smalloc(DMAP*sizeof(BSubfont*));
.
163c
#define	NINFO	8192	/* max chars per subfont; sanity check only */
.
87c
void	subfontfree(BSubfont*);
.
66c
	BSubfont**subfont;	/* indexed array */
.
57a
typedef struct	BSubfont BSubfont;
struct BSubfont
{
	GSubfont;
	int	ref;		/* number of times this subfont is open */
	ulong	qid[2];		/* unique id used as a cache tag */
};

.
## diffname port/devbit.c 1992/0628
## diff -e /n/bootesdump/1992/06271/sys/src/9/port/devbit.c /n/bootesdump/1992/0628/sys/src/9/port/devbit.c
1427,1429c
	s->ref--;
	return;
.
1362,1363d
1360c
	if(a->words){
		a->wfree = a->words;
		a->nbusy = 0;
		goto found;
	}

	/* free unused subfonts, compact, and try again */
	for(i=0; i<bit.nsubfont; i++){
		s = bit.subfont[i];
		if(s && s->ref==0){
			bitfree(s->bits);
			free(s->info);
			free(s);
			bit.subfont[i] = 0;
		}
	}
	bitcompact();
	for(a=bit.arena; a<ea; a++){
		if(a->words == 0)
			continue;
		if(a->wfree+HDR+nw <= a->words+a->nwords)
			goto found;
	}
	if(a == ea)
.
1307a
	BSubfont *s;
.
1253,1254c
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0 || f->ref==0)
				error(Ebadfont);
.
850a
			f->ref = 1;
.
814d
811a
			if(m < 9)
				error(Ebadblt);
			q0 = GLONG(p+1);
			q1 = GLONG(p+5);
			for(i=0; i<bit.nsubfont; i++){
				f = bit.subfont[i];
				if(f && f->qid[0]==q0 && f->qid[1]==q1)
					goto sfcachefound;
			}
			error(Esfnotcached);

		sfcachefound:
			f->ref++;
			bit.lastcachesf = i;
.
807c
			 * subfont cache check
.
772d
769c
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0 || f->ref==0)
.
762c
			 * free subfont
.
606c
	ulong l, nw, ws, rv, q0, q1;
.
508a
	}else if(bit.lastcachesf > 0){
		/*
		 * allocate subfont:
		 *	'J'		1
		 *	subfont id	2
		 *	font info	3*12
		 *	fontchars	6*(subfont->n+1)
		 */
		p[0] = 'J';
		PSHORT(p+1, bit.lastcachesf);
		s = bit.subfont[bit.lastcachesf];
		if(s==0 || n<3+3*12+6*(s->n+1))
			error(Ebadblt);
		p += 3;
		sprint((char*)p, "%11d %11d %11d ", s->n,
			s->height, s->ascent);
		p += 3*12;
		for(i=s->info,j=0; j<=s->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 = 3+3*12+6*(s->n+1);
		bit.lastcachesf = -1;
.
369a
	BSubfont *s;
.
340,341d
338c
				if(s)
.
274a
		bit.lastcachesf = -1;
.
79a
	int	lastcachesf;	/* last cached subfont id */
.
## diffname port/devbit.c 1992/0629
## diff -e /n/bootesdump/1992/0628/sys/src/9/port/devbit.c /n/bootesdump/1992/0629/sys/src/9/port/devbit.c
842,846c
			i = 0;
			if(q0 != ~0)
				for(; i<bit.nsubfont; i++){
					f = bit.subfont[i];
					if(f && f->qid[0]==q0 && f->qid[1]==q1)
						goto sfcachefound;
				}
.
## diffname port/devbit.c 1992/0630
## diff -e /n/bootesdump/1992/0629/sys/src/9/port/devbit.c /n/bootesdump/1992/0630/sys/src/9/port/devbit.c
1747c
		msg[nb] |= ~0xFF;	/* sign extend */
.
1700d
1624,1625c
	for(a=bit.arena; a<ea; a++)
		if(a->words && a->nbusy==0)
.
1622a
		memset(p1, 0, ((a->words+a->nwords)-p1)*sizeof(ulong));
.
1520c
		if(r >= f->ncache)
.
1517c
		r = BGSHORT(p);
.
1491c
	if(s != defont)	/* don't free subfont 0, defont */
		s->ref--;
.
1471,1475c
	if(b->base != gscreen.base){	/* can't free screen memory */
		a = (Arena*)(b->base[-2]);
if(a<bit.arena || a>=bit.arena+bit.narena) panic("bitfree");
		a->nbusy--;
		if(a->nbusy == 0)
			arenafree(a);
		b->base[-1] = 0;
	}
.
1435d
1412c
		if(s && s!=defont && s->ref==0){
.
1399,1407c
	/* else can't grow list: bitmaps have backpointers */
.
1391,1397c
		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){
			a->wfree = a->words;
			a->nbusy = 0;
			goto found;
		}
.
1389c
	if(aa){
.
1331c
				l = BGLONG(p-12);
.
1325c
				ok &= setcolor(i, BGLONG(p), BGLONG(p+4), BGLONG(p+8));
.
1315c
			v = BGSHORT(p+1);
.
1297c
			nw = BGSHORT(p+7);
.
1294c
			v = BGSHORT(p+5);
.
1291,1292c
			l = BGSHORT(p+3);
			if(l >= ff->ncache)
.
1288c
			v = BGSHORT(p+1);
.
1266,1267c
			pt1.x = BGLONG(p+1);
			pt1.y = BGLONG(p+5);
.
1223,1224c
			miny = BGLONG(p+3);
			maxy = BGLONG(p+7);
.
1217c
			v = BGSHORT(p+1);
.
1197c
			ff->width = BGSHORT(p+5);
.
1179,1180c
			v = BGSHORT(p+1);
			t = BGSHORT(p+3);
.
1153,1157c
			rect.min.x = BGLONG(p+3);
			rect.min.y = BGLONG(p+7);
			rect.max.x = BGLONG(p+11);
			rect.max.y = BGLONG(p+15);
			v = BGSHORT(p+19);
.
1147c
			fc = BGSHORT(p+21) & 0xF;
.
1143c
			v = BGSHORT(p+1);
.
1118c
			l = BGSHORT(p+15)*2;
.
1113,1115c
			pt.x = BGLONG(p+3);
			pt.y = BGLONG(p+7);
			v = BGSHORT(p+11);
.
1107c
			fc = BGSHORT(p+13) & 0xF;
.
1103c
			v = BGSHORT(p+1);
.
1079,1080c
			miny = BGLONG(p+3);
			maxy = BGLONG(p+7);
.
1076c
			v = BGSHORT(p+1);
.
1054,1057c
			rect.min.x = BGLONG(p+3);
			rect.min.y = BGLONG(p+7);
			rect.max.x = BGLONG(p+11);
			rect.max.y = BGLONG(p+15);
.
1051c
			v = BGSHORT(p+1);
.
1030,1031c
			pt1.x = BGLONG(p+3);
			pt1.y = BGLONG(p+7);
.
1024c
			fc = BGSHORT(p+12) & 0xF;
.
1020c
			v = BGSHORT(p+1);
.
1005c
			bit.fid = i;
.
980,981c
			v = BGSHORT(p+3);
			t = BGSHORT(p+5);
.
960c
			v = BGSHORT(p+1);
.
937,940c
			pt1.x = BGLONG(p+3);
			pt1.y = BGLONG(p+7);
			pt2.x = BGLONG(p+11);
			pt2.y = BGLONG(p+15);
.
931c
			fc = BGSHORT(p+20) & 0xF;
.
927c
			v = BGSHORT(p+1);
.
911c
			bit.subfid = i;
.
902c
				fcp->x = BGSHORT(p);
.
893c
			v = BGSHORT(p+5);
.
890,891c
			f->qid[0] = BGLONG(p+7);
			f->qid[1] = BGLONG(p+11);
.
872c
			v = BGSHORT(p+1);
.
853c
			bit.cacheid = i;
.
840,841c
			q0 = BGLONG(p+1);
			q1 = BGLONG(p+5);
.
811c
			v = BGSHORT(p+1);
.
795c
			v = BGSHORT(p+1);
.
778c
			v = BGSHORT(p+1);
.
757,758c
			curs.offset.x = BGLONG(p+1);
			curs.offset.y = BGLONG(p+5);
.
721,726c
			pt.x = BGLONG(p+3);
			pt.y = BGLONG(p+7);
			rect.min.x = BGLONG(p+13);
			rect.min.y = BGLONG(p+17);
			rect.max.x = BGLONG(p+21);
			rect.max.y = BGLONG(p+25);
.
713c
			v = BGSHORT(p+1);
.
703,704c
			fc = BGSHORT(p+29) & 0xF;
			v = BGSHORT(p+11);
.
686c
			bit.bid = bitalloc(rect, v);
.
680,683c
			rect.min.x = BGLONG(p+2);
			rect.min.y = BGLONG(p+6);
			rect.max.x = BGLONG(p+10);
			rect.max.y = BGLONG(p+14);
.
627d
609,611c
			if(bit.rid == 0)
				for(x=0; x<l; x++,p++,q++)
					BPLONG(p, ~*q);
.
569,571c
			BPLONG(p, rv);
			BPLONG(p+4, gv);
			BPLONG(p+8, bv);
.
545,546c
		BPSHORT(p+1, bit.fid);
		bit.fid = -1;
.
543a
		if(bit.fid<0 || bit.font[bit.fid]==0)
			error(Ebadfont);
.
535,536c
		bit.cacheid = -1;
	}else if(bit.fid >= 0){
.
528c
			BPSHORT(p, i->x);
.
524,525c
		sprint((char*)p, "%11d %11d %11d ", s->n, s->height, s->ascent);
.
522a
		BPSHORT(p+1, bit.cacheid);
.
519,521c
		if(bit.cacheid<0)
			error(Ebadfont);
		s = bit.subfont[bit.cacheid];
		if(s==0 || s->ref==0)
			error(Ebadfont);
		if(n < 3+3*12+6*(s->n+1))
.
510c
	}else if(bit.cacheid >= 0){
.
507,508c
		BPSHORT(p+1, bit.subfid);
		bit.subfid = -1;
.
505a
		s = bit.subfont[bit.subfid];
		if(s==0 || s->ref==0)
			error(Ebadfont);
.
504c
		if(n<3 || bit.subfid<0)
.
498c
	}else if(bit.subfid > 0){
.
495,496c
		BPSHORT(p+1, bit.bid);
		bit.bid = -1;
.
493a
		if(bit.bid<0 || bit.map[bit.bid]==0)
			error(Ebadbitmap);
.
486c
	}else if(bit.bid > 0){
.
476c
				BPSHORT(p, i->x);
.
462,469c
		BPLONG(p+2, gscreen.r.min.x);
		BPLONG(p+6, gscreen.r.min.y);
		BPLONG(p+10, gscreen.r.max.x);
		BPLONG(p+14, gscreen.r.max.y);
		BPLONG(p+18, gscreen.clipr.min.x);
		BPLONG(p+22, gscreen.clipr.min.y);
		BPLONG(p+26, gscreen.clipr.max.x);
		BPLONG(p+30, gscreen.clipr.max.y);
.
426,431c
			for(x=0; x<l; x++,p++,q++){
				v = *q;
				if(flipping)
					v = ~v;
				BPLONG(p, v);
			}
.
396,398c
		BPLONG(p+2, mouse.xy.x);
		BPLONG(p+6, mouse.xy.y);
		BPLONG(p+10, TK2MS(MACHP(0)->ticks));
.
366c
	ulong l, v, nw, ws, rv, gv, bv;
.
356,360d
341a
				/* don't clear *sp: cached */
.
338c
			for(sp=bit.subfont; sp<esp; sp++){
.
336d
328,329c
			for(bp = bit.map; bp<ebp; bp++){
.
322,326d
273,276c
		bit.bid = -1;
		bit.fid = -1;
		bit.subfid = -1;
		bit.cacheid = -1;
.
214,215d
188,190c
	bit.bid = -1;
	bit.subfid = -1;
	bit.fid = -1;
	bit.cacheid = -1;
.
78,81c
	int	bid;		/* last allocated bitmap id */
	int	subfid;		/* last allocated subfont id */
	int	cacheid;	/* last cached subfont id */
	int	fid;		/* last allocated font id */
.
## diffname port/devbit.c 1992/0702
## diff -e /n/bootesdump/1992/0630/sys/src/9/port/devbit.c /n/bootesdump/1992/0702/sys/src/9/port/devbit.c
1485a
		if(s->ref==0 && s->qid[0]==~0){	/* uncached */
			bitfree(s->bits);
			free(s->info);
			free(s);
			bit.subfont[i] = 0;
		}
	}
.
1484c
	if(s!=defont && s->ref>0){	/* don't free subfont 0, defont */
.
1482c
subfontfree(BSubfont *s, int i)
.
1404,1407c
			s->ref = 1;
			s->qid[0] = ~0;	/* force cleanup */
			subfontfree(s, i);
.
888a
			/* check to see if already there, uncache if so */
			for(j=0; j<bit.nsubfont; j++){
				if(j == i)
					continue;
				tf = bit.subfont[j];
				if(tf && tf->qid[0]==f->qid[0] && tf->qid[1]==f->qid[1])
					f->qid[0] = ~0;	/* uncached */
			}
.
833c
			 *	qid		8
.
795c
			subfontfree(f, v);
.
638c
	BSubfont *f, *tf, **fp;
.
512c
		if(bit.cacheid < 0)
.
333c
					subfontfree(s, sp-bit.subfont);
.
96c
void	subfontfree(BSubfont*, int);
.
## diffname port/devbit.c 1992/0703
## diff -e /n/bootesdump/1992/0702/sys/src/9/port/devbit.c /n/bootesdump/1992/0703/sys/src/9/port/devbit.c
1631d
1431a
	memset(a->wfree, 0, (nw-HDR)*sizeof(ulong));
.
## diffname port/devbit.c 1992/0704
## diff -e /n/bootesdump/1992/0703/sys/src/9/port/devbit.c /n/bootesdump/1992/0704/sys/src/9/port/devbit.c
1200,1206d
1187a
			x = BGSHORT(p+5);
			i = bitalloc(Rect(0, 0, t*x, ff->height), ff->ldepth);
			/* now committed */
			if(ff->b)
				bitfree(ff->b);
			ff->b = bit.map[i];
			bit.map[i] = 0;	/* disconnect it from GBitmap space */
			ff->width = x;
.
1176c
			 * clear font cache and bitmap.
			 * if error, font is unchanged.
.
895a
					break;
				}
.
894c
				if(tf && tf->qid[0]==f->qid[0] && tf->qid[1]==f->qid[1]){
.
175a
bitdebug(void)
{
	int i;
	long l;
	Arena *a;

	l = 0;
	for(i=0; i<bit.narena; i++){
		a = &bit.arena[i];
		if(a->words){
			l += a->nwords;
			print("%d: %ld used; %ld total\n", i,
				(a->wfree-a->words)*sizeof(ulong),
				a->nwords*sizeof(ulong));
		}
	}
	print("arena: %ld words\n", l*sizeof(ulong));
	l = 0;
	for(i=0; i<bit.nmap; i++)
		if(bit.map[i])
			l++;
	print("%d bitmaps ", l);
	l = 0;
	for(i=0; i<bit.nfont; i++)
		if(bit.font[i])
			l++;
	print("%d fonts ", l);
	l = 0;
	for(i=0; i<bit.nsubfont; i++)
		if(bit.subfont[i]){
			print("%d: %lux %lux ", i, bit.subfont[i]->qid[0], bit.subfont[i]->qid[1]);
			l++;
		}
	print("%d subfonts\n", l);
}

void
.
## diffname port/devbit.c 1992/0706
## diff -e /n/bootesdump/1992/0704/sys/src/9/port/devbit.c /n/bootesdump/1992/0706/sys/src/9/port/devbit.c
1512d
1494,1498c
		bp = bitmalloc((bit.nmap+DMAP)*sizeof(GBitmap*));
		if(bp == 0){
			bitfree(b);
			error(Enomem);
		}
		memmove(bp, bit.map, bit.nmap*sizeof(GBitmap*));
		free(bit.map);
		bit.map = bp;
		bp += bit.nmap;
.
1473c
	memset(a->wfree, 0, nw*sizeof(ulong));
.
1469c
	b = bitmalloc(sizeof(GBitmap));
	if(b == 0)
		error(Enomem);
.
1449,1458c
	bitfreeup();

.
1437c
		a->nwords = HDR + (gscreen.r.max.y*gscreen.r.max.x)/ws;
.
1401c
	ws = BI2WD>>ld;	/* pixels per word */
.
1236,1247d
1230c
			if(t != ff->ncache){
				gc = bitmalloc(t*sizeof(ff->cache[0]));
				if(gc == 0){
					bitfree(bit.map[i]);
					bit.map[i] = 0;
					error(Enomem);
				}
				free(ff->cache);
				ff->cache = gc;
				ff->ncache = t;
			}else{
				/*
				 * memset not necessary but helps avoid
				 * confusion if the cache is mishandled by the
				 * user.
				 */
				memset(ff->cache, 0, t*sizeof(ff->cache[0]));
			}
.
1039c
			ff->cache = bitmalloc(t*sizeof(GCacheinfo));
			if(ff->cache == 0){
				free(ff);
				error(Enomem);
			}
.
1037c
			ff = bitmalloc(sizeof(GFont));
			if(ff == 0)
				error(Enomem);
.
1031,1034c
			ffp = bitmalloc((bit.nfont+DMAP)*sizeof(GFont*));
			if(ffp == 0)
				error(Enomem);
			memmove(ffp, bit.font, bit.nfont*sizeof(GFont*));
			free(bit.font);
			bit.font = ffp;
.
920c
			f->info = bitmalloc((v+1)*sizeof(Fontchar));
			if(f->info == 0){
				free(f);
				error(Enomem);
			}
.
918c
			f = bitmalloc(sizeof(BSubfont));
			if(f == 0)
				error(Enomem);
.
912,915c
			fp = bitmalloc((bit.nsubfont+DMAP)*sizeof(BSubfont*));
			if(fp == 0)
				error(Enomem);
			memmove(fp, bit.subfont, bit.nsubfont*sizeof(BSubfont*));
			free(bit.subfont);
			bit.subfont = fp;
.
676a
	GCacheinfo *gc;
.
242,243c
	if(a->words == 0){
		/* try again */
		print("bitreset: allocating only 1 screenful\n");
		a->nwords /= 3;
		a->words = a->words = xalloc(a->nwords*sizeof(ulong));
		if(a->words == 0)
			panic("bitreset");
	}
.
240c
	ws = BI2WD>>gscreen.ldepth;	/* pixels per word */
	a->nwords = 3*(HDR + gscreen.r.max.y*gscreen.r.max.x/ws);
.
215c
	int i, ws;
.
175a
bitfreeup(void)
{
	int i;
	BSubfont *s;

	/* free unused subfonts and compact */
	for(i=0; i<bit.nsubfont; i++){
		s = bit.subfont[i];
		if(s && s!=defont && s->ref==0){
			s->ref = 1;
			s->qid[0] = ~0;	/* force cleanup */
			subfontfree(s, i);
		}
	}
	bitcompact();
}

void*
bitmalloc(ulong n)
{
	void *p;

	p = malloc(n);
	if(p)
		return p;
	bitfreeup();
	return malloc(n);
}

void
.
## diffname port/devbit.c 1992/0711
## diff -e /n/bootesdump/1992/0706/sys/src/9/port/devbit.c /n/bootesdump/1992/0711/sys/src/9/port/devbit.c
1677c
	Arena *a, *ea, *na;
.
1458d
1455d
1453c
	Arena *a, *ea, *aa;
.
715a
	USED(offset);

.
711c
	GBitmap *src, *dst;
.
703c
	long m, v, miny, maxy, t, x, y;
.
245,246c
	int ws;
.
## diffname port/devbit.c 1992/0720
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/devbit.c /n/bootesdump/1992/0720/sys/src/9/port/devbit.c
1631c
		}else if(c->left > 0)
			gbitblt(bp, pt, f->b,
				Rect(pt.x, pt.y, pt.x+c->left, pt.y+f->height),
				fc==S? 0 : F);
.
392a
		if(c->qid.path == Qmouse)
			bit.mouseopen = 0;
.
356a
	}
.
355c
		break;
	default:
.
333a
		if(bit.mouseopen){
			unlock(&bit);
			error(Einuse);
		}
		bit.mouseopen = 1;
		bit.ref++;
		unlock(&bit);
		break;
	case Qbitblt:
		lock(&bit);
.
332c
		break;
	case Qmouse:
.
329c
	switch(c->qid.path){
	case CHDIR:
.
77a
	int	mouseopen;	/* flag: mouse open */
.
## diffname port/devbit.c 1992/0729
## diff -e /n/bootesdump/1992/0720/sys/src/9/port/devbit.c /n/bootesdump/1992/0729/sys/src/9/port/devbit.c
1413a
			if(ff->b == 0)
				error(Ebadbitmap);
.
## diffname port/devbit.c 1992/0807
## diff -e /n/bootesdump/1992/0729/sys/src/9/port/devbit.c /n/bootesdump/1992/0807/sys/src/9/port/devbit.c
731a
	if(!conf.monitor)
		error(Egreg);
.
449a
	if(!conf.monitor)
		error(Egreg);
.
405a
	if(!conf.monitor)
		error(Egreg);
.
394a
	if(!conf.monitor)
		error(Egreg);
.
387a
	if(!conf.monitor)
		error(Egreg);
.
380a
	if(!conf.monitor)
		error(Egreg);
.
329a
	if(!conf.monitor)
		error(Egreg);
.
321a
	if(!conf.monitor)
		error(Egreg);
.
315a
	if(!conf.monitor)
		error(Egreg);
.
306a
	if(!conf.monitor)
		error(Egreg);
.
300a
	if(!conf.monitor)
		error(Egreg);
.
288a
	if(!conf.monitor)
		return;
.
249a
	if(!conf.monitor)
		return;
.
## diffname port/devbit.c 1992/0811
## diff -e /n/bootesdump/1992/0807/sys/src/9/port/devbit.c /n/bootesdump/1992/0811/sys/src/9/port/devbit.c
619c
		 * check cache for subfont:
.
## diffname port/devbit.c 1992/0816
## diff -e /n/bootesdump/1992/0811/sys/src/9/port/devbit.c /n/bootesdump/1992/0816/sys/src/9/port/devbit.c
1417c
			if(ptinrect(pt1, gscreen.r)){
.
1394,1401c
				oq = (uchar*)gaddr(dst, Pt(dst->r.min.x, y));
				q = oq + (dst->r.min.x&((sizeof(ulong))*ws-1))/ws;
				memmove(q, p, l);
				if(v==0 && flipping){	/* flip bits */
					/* we know it's all word aligned */
					lp = (ulong*)oq;
					for(x=0; x<l; x+=sizeof(ulong))
						*lp++ ^= ~0;
				}
				p += l;
.
744a
	ulong *lp;
.
742c
	uchar *p, *q, *oq;
.
725,726c
				p += l;
.
721,723c
			memmove(p, q, l);
			if(bit.rid==0 && flipping)
				/* is screen, so must be word aligned */
				for(x=0; x<l; x+=sizeof(ulong),p+=sizeof(ulong))
					*(ulong*)p ^= ~0;
.
528,533c
			memmove(p, q, l);
			if(flipping)
				/* is screen, so must be word aligned */
				for(x=0; x<l; x+=sizeof(ulong),p+=sizeof(ulong))
					*(ulong*)p ^= ~0;
			else
				p += l;
.
466c
	ulong l, nw, ws, rv, gv, bv;
.
## diffname port/devbit.c 1992/0818
## diff -e /n/bootesdump/1992/0816/sys/src/9/port/devbit.c /n/bootesdump/1992/0818/sys/src/9/port/devbit.c
1784a
	qunlock(&bitlock);
.
1731a
	qlock(&bitlock);
.
1725a
QLock	bitlock;

GBitmap*
id2bit(int v)
{
	GBitmap *bp=0;

	if(v<0 || v>=bit.nmap || (bp=bit.map[v])==0)
		error(Ebadbitmap);
	return bp;
}

.
## diffname port/devbit.c 1992/0820
## diff -e /n/bootesdump/1992/0818/sys/src/9/port/devbit.c /n/bootesdump/1992/0820/sys/src/9/port/devbit.c
223c
	print("arena: %ld bytes\n", l*sizeof(ulong));
.
218c
			print("%d: %ld bytes used; %ld total\n", i,
.
## diffname port/devbit.c 1992/0903
## diff -e /n/bootesdump/1992/0820/sys/src/9/port/devbit.c /n/bootesdump/1992/0903/sys/src/9/port/devbit.c
1681,1684c
		}else{
			if(c->left > 0)
				gbitblt(bp, pt, bp,
					Rect(pt.x, pt.y, pt.x+c->left, pt.y+f->height),
					clr);
			x = c->left+(c->xright-c->x);
			if(x < c->width)
				gbitblt(bp, Pt(pt.x+x, pt.y), bp,
					Rect(pt.x+x, pt.y, pt.x+c->width, pt.y+f->height),
					clr);
		}
.
1668a
		/* set clr to result under fc if source pixel is zero */
		/* hard to do without knowing layout of bits, so we cheat */
		clr = (fc&3);	/* fc&3 is result if source is zero */
		clr |= clr<<2;	/* fc&(3<<2) is result if source is one */
.
1665c
	clr = 0;
	full = (fc&~S)^(D&~S);	/* result involves source */
.
1663a
	int x;
	Fcode clr;
.
## diffname port/devbit.c 1992/0912
## diff -e /n/bootesdump/1992/0903/sys/src/9/port/devbit.c /n/bootesdump/1992/0912/sys/src/9/port/devbit.c
1638c
	if(s!=bdefont && s->ref>0){	/* don't free subfont 0, bdefont */
.
1262c
				error(Ebadfont);
.
585c
			n = 34+3*12+6*(bdefont->n+1);
.
578c
			for(i=bdefont->info,j=0; j<=bdefont->n; j++,i++,p+=6){
.
575,576c
			sprint((char*)p, "%11d %11d %11d ", bdefont->n,
				bdefont->height, bdefont->ascent);
.
573c
		if(n >= 34+3*12+6*(bdefont->n+1)){
.
559c
		 *	fontchars	6*(bdefont->n+1)
.
368c
		bit.subfont[0] = bdefont;	/* subfont 0 is default */
.
249a
	memmove(&bdefont0, defont, sizeof(*defont));
	bdefont = &bdefont0;
.
185c
		if(s && s!=bdefont && s->ref==0){
.
65a
extern GSubfont	*defont;
       BSubfont	*bdefont;
       BSubfont bdefont0;


.
14,15d
## diffname port/devbit.c 1992/0913
## diff -e /n/bootesdump/1992/0912/sys/src/9/port/devbit.c /n/bootesdump/1992/0913/sys/src/9/port/devbit.c
436a
		if(c->qid.path == Qbitblt)
			bit.bitbltopen = 0;
.
384c
		bit.bitbltopen = 1;
.
366c
		if(bit.bitbltopen || bit.mouseopen){
.
81a
	int	bitbltopen;	/* flag: bitblt open */
.
## diffname port/devbit.c 1992/0914
## diff -e /n/bootesdump/1992/0913/sys/src/9/port/devbit.c /n/bootesdump/1992/0914/sys/src/9/port/devbit.c
257a
	memmove(&bdefont0, defont, sizeof(*defont));
	bdefont = &bdefont0;
.
254,255d
## diffname port/devbit.c 1992/1010
## diff -e /n/bootesdump/1992/0914/sys/src/9/port/devbit.c /n/bootesdump/1992/1010/sys/src/9/port/devbit.c
1416a
			if(v == 0)
				hwscreenwrite(miny, maxy);
.
## diffname port/devbit.c 1992/1013
## diff -e /n/bootesdump/1992/1010/sys/src/9/port/devbit.c /n/bootesdump/1992/1013/sys/src/9/port/devbit.c
1869a
		if(islcd)
			mbbrect(cursor.r);
	}
.
1868c
	if(--cursor.visible == 0) {
.
1857a
		if(islcd)
			mbbrect(cursor.r);
.
1856c
		gbitblt(&gscreen, cursor.r.min,
.
1854c
		gbitblt(&gscreen, cursor.r.min,
.
1506a
	if(islcd) {
		screenupdate(mbb);
		mbb = Rect(10000, 10000, -10000, -10000);
	}
.
1395a
			if(islcd && dst->base < endscreen)
				mbbrect(Rect(dst->r.min.x, miny, dst->r.max.x, maxy));
.
1317a
			if(islcd && dst->base < endscreen)
				mbbrect(rect);
.
1280a
			if(islcd && dst->base < endscreen)
				mbbrect(Rpt(pt, add(pt, bitstrsize(ff, p, l))));
.
1190a
			if(islcd && dst->base < endscreen)
				mbbpt(pt1);
.
1091a
			if(islcd && dst->base < endscreen) {
				mbbpt(pt1);
				mbbpt(pt2);
			}
.
858a
			if(islcd && dst->base < endscreen)
				mbbrect(Rpt(pt, add(pt, sub(rect.max, rect.min))));
.
765a
	extern void screenupdate(Rectangle);
.
756a
	ulong *endscreen = gaddr(&gscreen, Pt(0, gscreen.r.max.y));
.
748a
static Rectangle mbb = {10000, 10000, -10000, -10000};

static void
mbbrect(Rectangle r)
{
	if (r.min.x < mbb.min.x)
		mbb.min.x = r.min.x;
	if (r.min.y < mbb.min.y)
		mbb.min.y = r.min.y;
	if (r.max.x > mbb.max.x)
		mbb.max.x = r.max.x;
	if (r.max.y > mbb.max.y)
		mbb.max.y = r.max.y;
}

static void
mbbpt(Point p)
{
	if (p.x < mbb.min.x)
		mbb.min.x = p.x;
	if (p.y < mbb.min.y)
		mbb.min.y = p.y;
	if (p.x >= mbb.max.x)
		mbb.max.x = p.x+1;
	if (p.y >= mbb.max.y)
		mbb.max.y = p.y+1;
}

Point
bitstrsize(GFont *f, uchar *p, int l)
{
	ushort r;
	Point s = {0,0};
	GCacheinfo *c;

	while(l > 0){
		r = BGSHORT(p);
		p += 2;
		l -= 2;
		if(r >= f->ncache)
			continue;
		c = &f->cache[r];
		if(c->bottom > s.y)
			s.y = c->bottom;
		s.x += c->width;
	}
	return s;
}

.
105a
extern	islcd;
.
## diffname port/devbit.c 1992/1015
## diff -e /n/bootesdump/1992/1013/sys/src/9/port/devbit.c /n/bootesdump/1992/1015/sys/src/9/port/devbit.c
1991a
	if(islcd)
		wakeup(&lcdmouse);
.
817d
750,751d
306a
	if(islcd)
		kproc("lcdmouse", lcdmousep, 0);
.
248a
lcdmousep(void *a)
{
	USED(a);
	for(;;){
		sleep(&lcdmouse, return0, 0);
		qlock(&bit);
		if(waserror()){
			qunlock(&bit);
			continue;
		}
		screenupdate(mbb);
		qunlock(&bit);
		poperror();
	}
}

void
.
247a
/*
 * need a process to do scsi transactions to update mouse on LCD
 */
.
163a
static Rectangle mbb = {10000, 10000, -10000, -10000};

.
109a
Rendez		lcdmouse;
.
## diffname port/devbit.c 1992/1020
## diff -e /n/bootesdump/1992/1015/sys/src/9/port/devbit.c /n/bootesdump/1992/1020/sys/src/9/port/devbit.c
2028a
/*
 *  microsoft 3 button, 7 bit bytes
 *
 *	byte 0 -	1  L  R Y7 Y6 X7 X6
 *	byte 1 -	0 X5 X4 X3 X2 X1 X0
 *	byte 2 -	0 Y5 Y4 Y3 Y2 Y1 Y0
 *	byte 3 -	0  M  x  x  x  x  x	(optional)
 *
 *  shift & left button is the same as middle button (for 2 button mice)
 */
int
m3mouseputc(IOQ *q, int c)
{
	static uchar msg[3];
	static int nb;
	static uchar b[] = { 0, 4, 1, 5, 0, 4, 3, 7 };
	short x;

	USED(q);
	/* 
	 *  check bit 6 for consistency
	 */
	if(nb==0){
		if((c&0x40) == 0){
			/* an extra byte gets sent for the middle button */
			mousebuttons((mouse.buttons & ~2) | ((c&0x20) ? 2 : 0));
			return 0;
		}
	}
	msg[nb] = c;
	if(++nb == 3){
		nb = 0;
		mouse.newbuttons = (mouse.buttons & 2)
				 | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
		x = (msg[0]&0x3)<<14;
		mouse.dx = (x>>8) | msg[1];
		x = (msg[0]&0xc)<<12;
		mouse.dy = (x>>8) | msg[2];
		mouse.track = 1;
		mouseclock();
	}
	return 0;
}

/*
 *  Logitech 5 byte packed binary mouse format, 8 bit bytes
 */
.
847a
	if(c->qid.path == Qmousectl){
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, va, n);
		buf[n] = 0;
		mousectl(buf);
		return n;
	}

.
839a
	char buf[64];
.
176a
	"mousectl",	{Qmousectl},	0,			0220,
.
170a
	Qmousectl,
.
110a
int		mouseshifted;
.
## diffname port/devbit.c 1992/1021
## diff -e /n/bootesdump/1992/1020/sys/src/9/port/devbit.c /n/bootesdump/1992/1021/sys/src/9/port/devbit.c
2103c
		mouse.newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 2 : 0)];
.
2094c
	static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 5, 3, 7};
.
2087a
 *
 *  shift & right button is the same as middle button (for 2 button mice)
.
2074,2075c
		mouse.newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
.
2067c
			middle = (c&0x20) ? 2 : 0;
			mousebuttons((mouse.buttons & ~2) | middle);
.
2057c
	static int middle;
	static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 5 };
.
2050c
 *  shift & right button is the same as middle button (for 2 button mice)
.
111a
int		mousetype;
int		islcd;
.
## diffname port/devbit.c 1992/1026
## diff -e /n/bootesdump/1992/1021/sys/src/9/port/devbit.c /n/bootesdump/1992/1026/sys/src/9/port/devbit.c
1112a
			bit.subfont[i] = f;
.
1107d
## diffname port/devbit.c 1992/1030
## diff -e /n/bootesdump/1992/1026/sys/src/9/port/devbit.c /n/bootesdump/1992/1030/sys/src/9/port/devbit.c
1594c
				ok &= setcolor(flipping ? ~i : i, BGLONG(p), BGLONG(p+4), BGLONG(p+8));
.
270a
		mbb = Rect(10000, 10000, -10000, -10000);
.
106d
10,11d
2a
#include	<libg.h>
#include	<gnot.h>
.
## diffname port/devbit.c 1992/1104
## diff -e /n/bootesdump/1992/1030/sys/src/9/port/devbit.c /n/bootesdump/1992/1104/sys/src/9/port/devbit.c
2029,2030c
	mousescreenupdate();
.
1979,1980c
		mbbrect(cursor.r);
.
1965,1966c
		mbbrect(cursor.r);
.
1610,1613c
	screenupdate();
.
1497c
			if(dst->base < endscreen)
.
1417c
			if(dst->base < endscreen)
.
1378c
			if(dst->base < endscreen)
.
1286c
			if(dst->base < endscreen)
.
1183c
			if(dst->base < endscreen) {
.
948c
			if(dst->base < endscreen)
.
780,805d
335,336d
259,276d
255,257d
188a
lockedupdate(void)
{
	qlock(&bit);
	if(waserror()){
		qunlock(&bit);
		return;
	}
	screenupdate();
	qunlock(&bit);
	poperror();
}

void
.
167,168d
112d
109d
## diffname port/devbit.c 1992/1106
## diff -e /n/bootesdump/1992/1104/sys/src/9/port/devbit.c /n/bootesdump/1992/1106/sys/src/9/port/devbit.c
2076a
}

/*
 *  swizzle a bitmap
 */
uchar cswizzle[] = {
	0x00,	0x80,	0x40,	0xc0,	0x20,	0xa0,	0x60,	0xe0,
	0x10,	0x90,	0x50,	0xd0,	0x30,	0xb0,	0x70,	0xf0,
	0x08,	0x88,	0x48,	0xc8,	0x28,	0xa8,	0x68,	0xe8,
	0x18,	0x98,	0x58,	0xd8,	0x38,	0xb8,	0x78,	0xf8,
	0x04,	0x84,	0x44,	0xc4,	0x24,	0xa4,	0x64,	0xe4,
	0x14,	0x94,	0x54,	0xd4,	0x34,	0xb4,	0x74,	0xf4,
	0x0c,	0x8c,	0x4c,	0xcc,	0x2c,	0xac,	0x6c,	0xec,
	0x1c,	0x9c,	0x5c,	0xdc,	0x3c,	0xbc,	0x7c,	0xfc,
	0x02,	0x82,	0x42,	0xc2,	0x22,	0xa2,	0x62,	0xe2,
	0x12,	0x92,	0x52,	0xd2,	0x32,	0xb2,	0x72,	0xf2,
	0x0a,	0x8a,	0x4a,	0xca,	0x2a,	0xaa,	0x6a,	0xea,
	0x1a,	0x9a,	0x5a,	0xda,	0x3a,	0xba,	0x7a,	0xfa,
	0x06,	0x86,	0x46,	0xc6,	0x26,	0xa6,	0x66,	0xe6,
	0x16,	0x96,	0x56,	0xd6,	0x36,	0xb6,	0x76,	0xf6,
	0x0e,	0x8e,	0x4e,	0xce,	0x2e,	0xae,	0x6e,	0xee,
	0x1e,	0x9e,	0x5e,	0xde,	0x3e,	0xbe,	0x7e,	0xfe,
	0x01,	0x81,	0x41,	0xc1,	0x21,	0xa1,	0x61,	0xe1,
	0x11,	0x91,	0x51,	0xd1,	0x31,	0xb1,	0x71,	0xf1,
	0x09,	0x89,	0x49,	0xc9,	0x29,	0xa9,	0x69,	0xe9,
	0x19,	0x99,	0x59,	0xd9,	0x39,	0xb9,	0x79,	0xf9,
	0x05,	0x85,	0x45,	0xc5,	0x25,	0xa5,	0x65,	0xe5,
	0x15,	0x95,	0x55,	0xd5,	0x35,	0xb5,	0x75,	0xf5,
	0x0d,	0x8d,	0x4d,	0xcd,	0x2d,	0xad,	0x6d,	0xed,
	0x1d,	0x9d,	0x5d,	0xdd,	0x3d,	0xbd,	0x7d,	0xfd,
	0x03,	0x83,	0x43,	0xc3,	0x23,	0xa3,	0x63,	0xe3,
	0x13,	0x93,	0x53,	0xd3,	0x33,	0xb3,	0x73,	0xf3,
	0x0b,	0x8b,	0x4b,	0xcb,	0x2b,	0xab,	0x6b,	0xeb,
	0x1b,	0x9b,	0x5b,	0xdb,	0x3b,	0xbb,	0x7b,	0xfb,
	0x07,	0x87,	0x47,	0xc7,	0x27,	0xa7,	0x67,	0xe7,
	0x17,	0x97,	0x57,	0xd7,	0x37,	0xb7,	0x77,	0xf7,
	0x0f,	0x8f,	0x4f,	0xcf,	0x2f,	0xaf,	0x6f,	0xef,
	0x1f,	0x9f,	0x5f,	0xdf,	0x3f,	0xbf,	0x7f,	0xff
};

void
bitreverse(uchar *p, int l)
{
	uchar *e;

	e = p + l;
	for(; p < e; p++)
		*p = cswizzle[*p];
.
1470a
				if(islittle)
					bitreverse(q, l);
.
938a
			if(islittle){
				bitreverse(curs.clr, 2*16);
				bitreverse(curs.set, 2*16);
			}
.
747a
			if(islittle)
				bitreverse(p, l);
.
110a
int		islittle;
.
## diffname port/devbit.c 1992/1107
## diff -e /n/bootesdump/1992/1106/sys/src/9/port/devbit.c /n/bootesdump/1992/1107/sys/src/9/port/devbit.c
2071c
		mouse.newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
.
1944a
		screenupdate();
.
1939a
	if(cursor.disable)
		return;
.
1931a
		screenupdate();
.
1919a
	if(cursor.disable)
		return;
.
1579d
1576a
	screenupdate();
.
1150c
			if(dst->base < endscreen){
.
935a
			if(m == 2){
				if(p[1]){	/* make damn sure */
					cursor.disable = 0;
					isoff = 1;
				}else{
					cursoroff(1);
					cursor.disable = 1;
				}
				m -= 2;
				p += 2;
				break;
			}
.
798c
 	ulong *endscreen = gaddr(&gscreen, Pt(0, gscreen.r.max.y));
.
## diffname port/devbit.c 1992/1108
## diff -e /n/bootesdump/1992/1107/sys/src/9/port/devbit.c /n/bootesdump/1992/1108/sys/src/9/port/devbit.c
2151c
		*p = bitrevtab[*p];
.
2109c
uchar bitrevtab[] = {
.
2107c
 *  reverse the bits in a bitmap (converting between little & big endian)
.
## diffname port/devbit.c 1992/1112
## diff -e /n/bootesdump/1992/1108/sys/src/9/port/devbit.c /n/bootesdump/1992/1112/sys/src/9/port/devbit.c
311a
/*
 *  screen bit depth changed, reset backup map for cursor
 */
void
bitdepth(void)
{
	cursoroff(1);
	if(gscreen.ldepth > 3)
		cursorback.ldepth = 0;
	else{
		cursorback.ldepth = gscreen.ldepth;
		cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5;
	}
	cursoron(1);
}

.
## diffname port/devbit.c 1992/1113
## diff -e /n/bootesdump/1992/1112/sys/src/9/port/devbit.c /n/bootesdump/1992/1113/sys/src/9/port/devbit.c
1978c
		mousescreenupdate();
.
1962d
1607a
	screenupdate();
.
1605d
## diffname port/devbit.c 1992/1115
## diff -e /n/bootesdump/1992/1113/sys/src/9/port/devbit.c /n/bootesdump/1992/1115/sys/src/9/port/devbit.c
2164,2166c
	switch(ldepth){
	case 0:
		tab = revtab0;
		break;
	case 1:
		tab = revtab1;
		break;
	case 2:
		tab = revtab2;
		break;
	default:
		return;
	}

	for(e = p + len; p < e; p++)
		*p = tab[*p];
.
2162a
	uchar *tab;
.
2160c
pixreverse(uchar *p, int len, int ldepth)
.
2157a
uchar revtab1[] = {
 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0,
 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0,
 0x04, 0x44, 0x84, 0xc4, 0x14, 0x54, 0x94, 0xd4,
 0x24, 0x64, 0xa4, 0xe4, 0x34, 0x74, 0xb4, 0xf4,
 0x08, 0x48, 0x88, 0xc8, 0x18, 0x58, 0x98, 0xd8,
 0x28, 0x68, 0xa8, 0xe8, 0x38, 0x78, 0xb8, 0xf8,
 0x0c, 0x4c, 0x8c, 0xcc, 0x1c, 0x5c, 0x9c, 0xdc,
 0x2c, 0x6c, 0xac, 0xec, 0x3c, 0x7c, 0xbc, 0xfc,
 0x01, 0x41, 0x81, 0xc1, 0x11, 0x51, 0x91, 0xd1,
 0x21, 0x61, 0xa1, 0xe1, 0x31, 0x71, 0xb1, 0xf1,
 0x05, 0x45, 0x85, 0xc5, 0x15, 0x55, 0x95, 0xd5,
 0x25, 0x65, 0xa5, 0xe5, 0x35, 0x75, 0xb5, 0xf5,
 0x09, 0x49, 0x89, 0xc9, 0x19, 0x59, 0x99, 0xd9,
 0x29, 0x69, 0xa9, 0xe9, 0x39, 0x79, 0xb9, 0xf9,
 0x0d, 0x4d, 0x8d, 0xcd, 0x1d, 0x5d, 0x9d, 0xdd,
 0x2d, 0x6d, 0xad, 0xed, 0x3d, 0x7d, 0xbd, 0xfd,
 0x02, 0x42, 0x82, 0xc2, 0x12, 0x52, 0x92, 0xd2,
 0x22, 0x62, 0xa2, 0xe2, 0x32, 0x72, 0xb2, 0xf2,
 0x06, 0x46, 0x86, 0xc6, 0x16, 0x56, 0x96, 0xd6,
 0x26, 0x66, 0xa6, 0xe6, 0x36, 0x76, 0xb6, 0xf6,
 0x0a, 0x4a, 0x8a, 0xca, 0x1a, 0x5a, 0x9a, 0xda,
 0x2a, 0x6a, 0xaa, 0xea, 0x3a, 0x7a, 0xba, 0xfa,
 0x0e, 0x4e, 0x8e, 0xce, 0x1e, 0x5e, 0x9e, 0xde,
 0x2e, 0x6e, 0xae, 0xee, 0x3e, 0x7e, 0xbe, 0xfe,
 0x03, 0x43, 0x83, 0xc3, 0x13, 0x53, 0x93, 0xd3,
 0x23, 0x63, 0xa3, 0xe3, 0x33, 0x73, 0xb3, 0xf3,
 0x07, 0x47, 0x87, 0xc7, 0x17, 0x57, 0x97, 0xd7,
 0x27, 0x67, 0xa7, 0xe7, 0x37, 0x77, 0xb7, 0xf7,
 0x0b, 0x4b, 0x8b, 0xcb, 0x1b, 0x5b, 0x9b, 0xdb,
 0x2b, 0x6b, 0xab, 0xeb, 0x3b, 0x7b, 0xbb, 0xfb,
 0x0f, 0x4f, 0x8f, 0xcf, 0x1f, 0x5f, 0x9f, 0xdf,
 0x2f, 0x6f, 0xaf, 0xef, 0x3f, 0x7f, 0xbf, 0xff,
};
uchar revtab2[] = {
 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
 0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, 0xf1,
 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
 0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0xe2, 0xf2,
 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
 0x83, 0x93, 0xa3, 0xb3, 0xc3, 0xd3, 0xe3, 0xf3,
 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
 0x84, 0x94, 0xa4, 0xb4, 0xc4, 0xd4, 0xe4, 0xf4,
 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
 0x85, 0x95, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5,
 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6,
 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7,
 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
 0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8,
 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
 0x89, 0x99, 0xa9, 0xb9, 0xc9, 0xd9, 0xe9, 0xf9,
 0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a,
 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa,
 0x0b, 0x1b, 0x2b, 0x3b, 0x4b, 0x5b, 0x6b, 0x7b,
 0x8b, 0x9b, 0xab, 0xbb, 0xcb, 0xdb, 0xeb, 0xfb,
 0x0c, 0x1c, 0x2c, 0x3c, 0x4c, 0x5c, 0x6c, 0x7c,
 0x8c, 0x9c, 0xac, 0xbc, 0xcc, 0xdc, 0xec, 0xfc,
 0x0d, 0x1d, 0x2d, 0x3d, 0x4d, 0x5d, 0x6d, 0x7d,
 0x8d, 0x9d, 0xad, 0xbd, 0xcd, 0xdd, 0xed, 0xfd,
 0x0e, 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e,
 0x8e, 0x9e, 0xae, 0xbe, 0xce, 0xde, 0xee, 0xfe,
 0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f,
 0x8f, 0x9f, 0xaf, 0xbf, 0xcf, 0xdf, 0xef, 0xff,
};
.
2124,2156c
uchar revtab0[] = {
 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
.
2122c
 *  reverse pixels into little endian order
.
1507c
					pixreverse(q, l, dst->ldepth);
.
971,972c
				pixreverse(curs.clr, 2*16, 0);
				pixreverse(curs.set, 2*16, 0);
.
766c
				pixreverse(p, l, src->ldepth);
.
## diffname port/devbit.c 1992/1207
## diff -e /n/bootesdump/1992/1115/sys/src/9/port/devbit.c /n/bootesdump/1992/1207/sys/src/9/port/devbit.c
982a
		case 'e':
			/*
			 * polysegment
			 *
			 *	'e'		1
			 *	id		2
			 *	pt		8
			 *	value		1
			 *	code		2
			 *	n		2
			 *	pts		2*n
			 */
			if(m < 16)
				error(Ebadblt);
			l = BGSHORT(p+14);
			if(m < 16+2*l)
				error(Ebadblt);
			v = BGSHORT(p+1);
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
				error(Ebadbitmap);
			off = 0;
			fc = BGSHORT(p+12) & 0xF;
			if(v == 0){
				if(flipping)
					fc = flipD[fc];
				off = 1;
			}
			pt1.x = BGLONG(p+3);
			pt1.y = BGLONG(p+7);
			t = p[11];
			if(off && !isoff){
				cursoroff(1);
				isoff = 1;
			}
			p += 16;
			m -= 16;
			while(l > 0){
				pt2.x = pt1.x + (schar)p[0];
				pt2.y = pt1.y + (schar)p[1];
				gsegment(dst, pt1, pt2, t, fc);
				if(dst->base < endscreen){
					mbbpt(pt1);
					mbbpt(pt2);
				}
				pt1 = pt2;
				p += 2;
				m -= 2;
				l--;
			}
			break;

.
## diffname port/devbit.c 1992/1216
## diff -e /n/bootesdump/1992/1207/sys/src/9/port/devbit.c /n/bootesdump/1992/1216/sys/src/9/port/devbit.c
162,163d
## diffname port/devbit.c 1993/0103
## diff -e /n/bootesdump/1992/1216/sys/src/9/port/devbit.c /n/bootesdump/1993/0103/sys/src/9/port/devbit.c
934a
			 * if one more byte, says whether to disable
			 * because of stupid lcd's (thank you bart)
			 * else
.
## diffname port/devbit.c 1993/0225
## diff -e /n/bootesdump/1993/0103/sys/src/9/port/devbit.c /n/bootesdump/1993/0225/sys/src/9/port/devbit.c
2170c
	return mouse.lastcounter != mouse.counter;
.
2084c
	mouse.counter++;
.
541c
		mouse.lastcounter = mouse.counter;
.
531,534d
527,528c
		while(mousechanged(0) == 0)
.
## diffname port/devbit.c 1993/0226
## diff -e /n/bootesdump/1993/0225/sys/src/9/port/devbit.c /n/bootesdump/1993/0226/sys/src/9/port/devbit.c
2151,2155c
		newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
		dx = msg[1]+msg[3];
		dy = -(msg[2]+msg[4]);
		mousetrack(newbuttons, dx, dy);
.
2142a
	int dx, dy, newbuttons;
.
2125,2127c
		dy = (x>>8) | msg[2];
		mousetrack(newbuttons, dx, dy);
.
2123c
		dx = (x>>8) | msg[1];
.
2121c
		newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
.
2114c
			newbuttons = (mouse.buttons & ~2) | middle;
			mousetrack(newbuttons, 0, 0);
.
2104a
	int dx, dy, newbuttons;
.
2080,2084c
	mouse.xy = Pt(x, y);
	mouse.buttons = b;
	mouse.redraw = 1;
	wakeup(&mouse.r);
.
2070,2078d
2065c
	y = mouse.xy.y + dy;
.
2057,2060c
	x = mouse.xy.x + dx;
.
2042,2054d
2040c
mousetrack(int b, int dx, int dy)
.
2038a
/*
 *  called at interrupt level to update the structure and
 *  awaken any waiting procs.
 */
.
2033,2036c
	if(mouse.track){
		mousetrack(mouse.buttons, mouse.dx, mouse.dy);
		mouse.track = 0;
		mouse.dx = 0;
		mouse.dy = 0;
	}
	if(mouse.redraw && canlock(&cursor)){
		mouse.redraw = 0;
		cursoroff(0);
		cursoron(0);
		mousescreenupdate();
		unlock(&cursor);
	}
.
2031c
mouseclock(void)
.
2029a
/*
 *  called by the clock routine to redraw the cursor
 */
.
1581c
				mouse.redraw = 1;
.
106a
typedef struct Mouseinfo	Mouseinfo;
typedef struct Cursorinfo	Cursorinfo;

struct Mouseinfo{
	/*
	 * First three fields are known in some l.s's
	 */
	int	dx;
	int	dy;
	int	track;		/* l.s has updated dx & dy */
	Mouse;
	int	redraw;		/* update cursor on screen */
	ulong	counter;	/* increments every update */
	ulong	lastcounter;	/* value when /dev/mouse read */
	Rendez	r;
};

struct Cursorinfo{
	Cursor;
	Lock;
	int	visible;	/* on screen */
	int	disable;	/* from being used */
	Rectangle r;		/* location */
};

.
## diffname port/devbit.c 1993/0313
## diff -e /n/bootesdump/1993/0226/sys/src/9/port/devbit.c /n/bootesdump/1993/0313/sys/src/9/port/devbit.c
1606a
				mouse.track = 1;
.
## diffname port/devbit.c 1993/0415
## diff -e /n/bootesdump/1993/0313/sys/src/9/port/devbit.c /n/bootesdump/1993/0415/sys/src/9/port/devbit.c
735c
				getcolor(flipping? nw-j-1 : j, &rv, &gv, &bv);
.
## diffname port/devbit.c 1993/0501
## diff -e /n/bootesdump/1993/0415/sys/src/9/port/devbit.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devbit.c
2182c
	return mouse.changed;
.
2169,2172c
		mouse.newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
		mouse.dx = msg[1]+msg[3];
		mouse.dy = -(msg[2]+msg[4]);
		mouse.track = 1;
		mouseclock();
.
2160d
2143,2144c
		mouse.dy = (x>>8) | msg[2];
		mouse.track = 1;
		mouseclock();
.
2141c
		mouse.dx = (x>>8) | msg[1];
.
2139c
		mouse.newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
.
2131,2132c
			mousebuttons((mouse.buttons & ~2) | middle);
.
2121d
2098,2100c
	cursoron(0);
	mousescreenupdate();
	mouse.dx = 0;
	mouse.dy = 0;
	mouse.clock = 0;
	mouse.track = 0;
	mouse.buttons = mouse.newbuttons;
	mouse.changed = 1;

	if(dolock){
		unlock(&cursor);
		wakeup(&mouse.r);
	}
.
2096c
	cursoroff(0);
.
2091c
	y = mouse.xy.y + mouse.dy;
.
2086c
	if(!mouse.track || (dolock && !canlock(&cursor)))
		return;

	x = mouse.xy.x + mouse.dx;
.
2083a
	/*
	 * It is possible if you click very fast and get bad luck
	 * you could miss a button click (down up).  Doesn't seem
	 * likely or important enough to worry about.
	 */
	mouse.newbuttons = b;
	mouse.track = 1;		/* aggressive but o.k. */
	mouseclock();
}

void
mouseupdate(int dolock)
{
.
2082c
mousebuttons(int b)	/* called at higher priority */
.
2077,2080d
2062,2074c
	mouse.dx += dx;
	mouse.dy += dy;
	mouse.newbuttons = b;
	mouse.track = 1;
.
2060c
mousedelta(int b, int dx, int dy)	/* called at higher priority */
.
2056,2058d
1606d
735c
				getcolor(flipping? ~j : j, &rv, &gv, &bv);
.
561c
		mouse.changed = 0;
.
554a
		if(mouse.changed == 0){
			unlock(&cursor);
			goto Again;
		}
.
552c
	    Again:
		while(mouse.changed == 0)
.
107,131d
## diffname port/devbit.c 1993/0906
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devbit.c /n/fornaxdump/1993/0906/sys/src/brazil/port/devbit.c
2170c
	return mouse.lastcounter != mouse.counter;
.
2156,2160c
		newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
		dx = msg[1]+msg[3];
		dy = -(msg[2]+msg[4]);
		mousetrack(newbuttons, dx, dy);
.
2147a
	int dx, dy, newbuttons;
.
2130,2132c
		dy = (x>>8) | msg[2];
		mousetrack(newbuttons, dx, dy);
.
2128c
		dx = (x>>8) | msg[1];
.
2126c
		newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
.
2119c
			newbuttons = (mouse.buttons & ~2) | middle;
			mousetrack(newbuttons, 0, 0);
.
2109a
	int dx, dy, newbuttons;
.
2077,2089c
	mouse.buttons = b;
	mouse.redraw = 1;
	wakeup(&mouse.r);
.
2075c
	mouse.counter++;
.
2070c
	y = mouse.xy.y + dy;
.
2062,2065c
	x = mouse.xy.x + dx;
.
2047,2059d
2045c
mousetrack(int b, int dx, int dy)
.
2043a
/*
 *  called at interrupt level to update the structure and
 *  awaken any waiting procs.
 */
.
2038,2041c
	if(mouse.track){
		mousetrack(mouse.buttons, mouse.dx, mouse.dy);
		mouse.track = 0;
		mouse.dx = 0;
		mouse.dy = 0;
	}
	if(mouse.redraw && canlock(&cursor)){
		mouse.redraw = 0;
		cursoroff(0);
		cursoron(0);
		mousescreenupdate();
		unlock(&cursor);
	}
.
2036c
mouseclock(void)
.
2034a
/*
 *  called by the clock routine to redraw the cursor
 */
.
2027,2029c
		if(!hwcurs) {
			gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
			mbbrect(cursor.r);
			mousescreenupdate();
		}
.
2005,2013c
		if(hwcurs)
			hwcursmove(mouse.xy.x, mouse.xy.y);
		else {
			cursor.r.min = mouse.xy;
			cursor.r.max = add(mouse.xy, Pt(16, 16));
			cursor.r = raddp(cursor.r, cursor.offset);
			gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S);
			gbitblt(&gscreen, cursor.r.min,
				&clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S);
			gbitblt(&gscreen, cursor.r.min,
				&set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D);
			mbbrect(cursor.r);
		}
.
1993a
	if(hwcurs)
		hwcursset(set.base, clr.base, cursor.offset.x, cursor.offset.y);
.
1585a
				mouse.redraw = 1;
.
1569,1570d
715c
				getcolor(flipping? nw-j-1 : j, &rv, &gv, &bv);
.
549c
			sprint(va, "%11d %11d %11d %11d %11d",
.
541c
		mouse.lastcounter = mouse.counter;
.
531,534d
527,528c
		while(mousechanged(0) == 0)
.
293a

.
271a

.
111a
int		hwcurs;
.
106a
typedef struct Mouseinfo	Mouseinfo;
typedef struct Cursorinfo	Cursorinfo;

struct Mouseinfo{
	/*
	 * First three fields are known in some l.s's
	 */
	int	dx;
	int	dy;
	int	track;		/* l.s has updated dx & dy */
	Mouse;
	int	redraw;		/* update cursor on screen */
	ulong	counter;	/* increments every update */
	ulong	lastcounter;	/* value when /dev/mouse read */
	Rendez	r;
};

struct Cursorinfo{
	Cursor;
	Lock;
	int	visible;	/* on screen */
	int	disable;	/* from being used */
	Rectangle r;		/* location */
};

.
12,13d
## diffname port/devbit.c 1993/0907
## diff -e /n/fornaxdump/1993/0906/sys/src/brazil/port/devbit.c /n/fornaxdump/1993/0907/sys/src/brazil/port/devbit.c
845,846d
538,539d
490,491d
477,478d
468,469d
406,407d
396,397d
388,389d
377,378d
## diffname port/devbit.c 1993/1003
## diff -e /n/fornaxdump/1993/0907/sys/src/brazil/port/devbit.c /n/fornaxdump/1993/1003/sys/src/brazil/port/devbit.c
122c
struct Cursorinfo
{
.
108c
struct Mouseinfo
{
.
## diffname port/devbit.c 1993/1124 # deleted
## diff -e /n/fornaxdump/1993/1003/sys/src/brazil/port/devbit.c /n/fornaxdump/1993/1124/sys/src/brazil/port/devbit.c
1,2304d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.