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

1990/0324/port/devbit.c (diff list | history)

port/devbit.c on 1990/0324
1990/0324    
#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); 
} 


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