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

1997/1101/pc/screen.c (diff list | history)

1993/1113/sys/src/9/pc/screen.c:4,3091997/1101/sys/src/9/pc/screen.c:4,298 (short | long)
1993/1113    
#include "dat.h" 
#include "fns.h" 
#include "io.h" 
1997/1101    
#include "ureg.h" 
1993/1113    
#include "../port/error.h" 
 
#include <libg.h> 
#include <gnot.h> 
1997/1101    
#define	Image	IMAGE 
#include <draw.h> 
#include <memdraw.h> 
1993/1113    
#include "screen.h" 
#include "vga.h" 
 
/* 
 * CGA-only hack. 
 */ 
/* imported */ 
extern	GSubfont defont0; 
extern	Cursor arrow; 
extern	GBitmap cursorback; 
                 
/* exported */ 
GSubfont *defont; 
int islittle = 1;		/* little endian bit ordering in bytes */ 
GBitmap	gscreen; 
                 
/* local */ 
static	Lock vgalock; 
static	ulong colormap[256][3]; 
static	Rectangle mbb; 
                 
/* 
 *  reverse pixels into little endian order 
 */ 
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, 
1997/1101    
static ulong onesbits = ~0; 
static Memdata onesdata = { 
	nil, 
	&onesbits, 
1993/1113    
}; 
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, 
1997/1101    
static Memimage xones = { 
	{ 0, 0, 1, 1 }, 
	{ -100000, -100000, 100000, 100000 }, 
	3, 
	1, 
	&onesdata, 
	0, 
	1 
1993/1113    
}; 
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, 
}; 
1997/1101    
Memimage *memones = &xones; 
1993/1113    
 
void 
pixreverse(uchar *p, int len, int ldepth) 
{ 
	uchar *e; 
	uchar *tab; 
1997/1101    
Point ZP = {0, 0}; 
1993/1113    
 
	switch(ldepth){ 
	case 0: 
		tab = revtab0; 
		break; 
	case 1: 
		tab = revtab1; 
		break; 
	case 2: 
		tab = revtab2; 
		break; 
	default: 
		return; 
	} 
1997/1101    
Memdata gscreendata; 
Memimage gscreen; 
1993/1113    
 
	for(e = p + len; p < e; p++) 
		*p = tab[*p]; 
} 
1997/1101    
VGAscr vgascreen[1]; 
1993/1113    
 
static void 
crout(int reg, int val) 
1997/1101    
int 
screensize(int x, int y, int z) 
1993/1113    
{ 
	outb(CRX, reg); 
	outb(CR, val); 
} 
1997/1101    
	VGAscr *scr; 
1993/1113    
 
void 
screeninit(void) 
{ 
	int i; 
	ulong *l; 
1997/1101    
	scr = &vgascreen[0]; 
1993/1113    
 
	/* 
	 *  arrow is defined as a big endian 
1997/1101    
	 * BUG: need to check if any xalloc'ed memory needs to 
	 * be given back if aperture is set. 
1993/1113    
	 */ 
	pixreverse(arrow.set, 2*16, 0); 
	pixreverse(arrow.clr, 2*16, 0); 
1997/1101    
	if(scr->aperture == 0){ 
		int width = (x*(1<<z))/BI2WD; 
1993/1113    
 
	/* 
	 *  swizzle the font longs.  we do both byte and bit swizzling 
	 *  since the font is initialized with big endian longs. 
	 */ 
	defont = &defont0; 
	l = defont->bits->base; 
	for(i = defont->bits->width*Dy(defont->bits->r); i > 0; i--, l++) 
		*l = (*l<<24) | ((*l>>8)&0x0000ff00) | ((*l<<8)&0x00ff0000) | (*l>>24); 
	pixreverse((uchar*)defont->bits->base, 
		defont->bits->width*BY2WD*Dy(defont->bits->r), 0); 
1997/1101    
		gscreendata.data = xalloc(width*BY2WD*y); 
		if(gscreendata.data == 0) 
			error("screensize: vga soft memory"); 
		memset(gscreendata.data, Backgnd, width*BY2WD*y); 
		scr->useflush = 1; 
1993/1113    
 
	crout(0x0a, 0xff);		/* turn off cursor */ 
	memset(CGASCREEN, 0, CGAWIDTH*CGAHEIGHT); 
1997/1101    
		scr->aperture = 0xA0000; 
		scr->apsize = 1<<16; 
	} 
	else 
		gscreendata.data = KADDR(scr->aperture); 
 
	gscreen.data = &gscreendata; 
	gscreen.ldepth = z; 
	gscreen.width = (x*(1<<gscreen.ldepth)+31)/32; 
	gscreen.r.min = ZP; 
	gscreen.r.max = Pt(x, y); 
	gscreen.clipr = gscreen.r; 
	gscreen.repl = 0; 
 
	scr->gscreendata = gscreen.data; 
	scr->memdefont = getmemdefont(); 
	scr->gscreen = &gscreen; 
 
//	memset(gscreen.data->data, Backgnd, scr->apsize); 
 
	drawcmap(0); 
 
	return 0; 
1993/1113    
} 
 
static void 
cgascreenputc(int c) 
1997/1101    
int 
screenaperture(int size, int align) 
1993/1113    
{ 
	int i; 
	static int color; 
	static int pos; 
1997/1101    
	VGAscr *scr; 
	ulong aperture; 
1993/1113    
 
	if(c == '\n'){ 
		pos = pos/CGAWIDTH; 
		pos = (pos+1)*CGAWIDTH; 
	} else if(c == '\t'){ 
		i = 8 - ((pos/2)&7); 
		while(i-->0) 
			cgascreenputc(' '); 
	} else if(c == '\b'){ 
		if(pos >= 2) 
			pos -= 2; 
		cgascreenputc(' '); 
		pos -= 2; 
	} else { 
		CGASCREEN[pos++] = c; 
		CGASCREEN[pos++] = 2;	/* green on black */ 
1997/1101    
	scr = &vgascreen[0]; 
 
	if(size == 0){ 
		if(scr->aperture && scr->isupamem) 
			upafree(scr->aperture, scr->apsize); 
		scr->aperture = 0; 
		scr->isupamem = 0; 
		return 0; 
1993/1113    
	} 
	if(pos >= CGAWIDTH*CGAHEIGHT){ 
		memmove(CGASCREEN, &CGASCREEN[CGAWIDTH], CGAWIDTH*(CGAHEIGHT-1)); 
		memset(&CGASCREEN[CGAWIDTH*(CGAHEIGHT-1)], 0, CGAWIDTH); 
		pos = CGAWIDTH*(CGAHEIGHT-1); 
1997/1101    
	if(scr->dev && scr->dev->linear){ 
		aperture = scr->dev->linear(scr, &size, &align); 
		if(aperture == 0) 
			return 1; 
1993/1113    
	} 
1997/1101    
	else{ 
		aperture = upamalloc(0, size, align); 
		if(aperture == 0) 
			return 1; 
 
		if(scr->aperture && scr->isupamem) 
			upafree(scr->aperture, scr->apsize); 
		scr->isupamem = 1; 
	} 
 
	scr->aperture = aperture; 
	scr->apsize = size; 
 
	return 0; 
1993/1113    
} 
 
void 
screenputs(char *s, int n) 
1997/1101    
ulong* 
attachscreen(Rectangle* r, int* ld, int* width) 
1993/1113    
{ 
	while(n-- > 0) 
		cgascreenputc(*s++); 
1997/1101    
	VGAscr *scr; 
 
	scr = &vgascreen[0]; 
	if(scr->gscreen == nil || scr->gscreendata == nil) 
		return nil; 
 
	*r = scr->gscreen->r; 
	*ld = scr->gscreen->ldepth; 
	*width = scr->gscreen->width; 
 
	return scr->gscreendata->data; 
1993/1113    
} 
 
/* 
 *  collect changes to the 'soft' screen 
 */ 
void 
mbbrect(Rectangle r) 
1997/1101    
flushmemscreen(Rectangle r) 
1993/1113    
{ 
	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; 
	mousescreenupdate(); 
1997/1101    
	VGAscr *scr; 
	uchar *sp, *disp, *sdisp, *edisp; 
	int y, len, incs, off, page; 
 
	scr = &vgascreen[0]; 
	if(scr->gscreen == nil || scr->useflush == 0) 
		return; 
	if(scr->dev == nil || scr->dev->page == nil) 
		return; 
 
	if(rectclip(&r, scr->gscreen->r) == 0) 
		return; 
 
	incs = scr->gscreen->width * BY2WD; 
 
	switch(scr->gscreen->ldepth){ 
	default: 
		len = 0; 
		panic("flushmemscreen: ldepth\n"); 
		break; 
	case 3: 
		len = Dx(r); 
		break; 
	} 
	if(len < 1) 
		return; 
 
	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x>>(3-scr->gscreen->ldepth)); 
	page = off/scr->apsize; 
	off %= scr->apsize; 
	disp = KADDR(scr->aperture); 
	sdisp = disp+off; 
	edisp = disp+scr->apsize; 
 
	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x>>(3-scr->gscreen->ldepth)); 
	sp = ((uchar*)scr->gscreendata->data) + off; 
 
	scr->dev->page(scr, page); 
	for(y = r.min.y; y < r.max.y; y++) { 
		if(sdisp + incs < edisp) { 
			memmove(sdisp, sp, len); 
			sp += incs; 
			sdisp += incs; 
		} 
		else { 
			off = edisp - sdisp; 
			page++; 
			if(off <= len){ 
				if(off > 0) 
					memmove(sdisp, sp, off); 
				scr->dev->page(scr, page); 
				if(len - off > 0) 
					memmove(disp, sp+off, len - off); 
			} 
			else { 
				memmove(sdisp, sp, len); 
				scr->dev->page(scr, page); 
			} 
			sp += incs; 
			sdisp += incs - scr->apsize; 
		} 
	} 
1993/1113    
} 
 
void 
hwcursset(ulong *s, ulong *c, int ox, int oy) 
1997/1101    
getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb) 
1993/1113    
{ 
	USED(s, c, ox, oy); 
1997/1101    
	VGAscr *scr; 
	ulong x; 
 
	scr = &vgascreen[0]; 
	if(scr->gscreen == nil) 
		return; 
 
	switch(scr->gscreen->ldepth){ 
	default: 
		x = 0x0F; 
		break; 
	case 3: 
		x = 0xFF; 
		break; 
	} 
	p &= x; 
	p ^= x; 
 
	lock(&cursor); 
	*pr = scr->colormap[p][0]; 
	*pg = scr->colormap[p][1]; 
	*pb = scr->colormap[p][2]; 
	unlock(&cursor); 
1993/1113    
} 
 
void 
hwcursmove(int x, int y) 
1997/1101    
int 
setcolor(ulong p, ulong r, ulong g, ulong b) 
1993/1113    
{ 
	USED(x, y); 
1997/1101    
	VGAscr *scr; 
	ulong x; 
 
	scr = &vgascreen[0]; 
	if(scr->gscreen == nil) 
		return 0; 
 
	switch(scr->gscreen->ldepth){ 
	default: 
		x = 0x0F; 
		break; 
	case 3: 
		x = 0xFF; 
		break; 
	} 
	p &= x; 
	p ^= x; 
 
	lock(&cursor); 
	scr->colormap[p][0] = r; 
	scr->colormap[p][1] = g; 
	scr->colormap[p][2] = b; 
	vgao(PaddrW, p); 
	vgao(Pdata, r>>(32-6)); 
	vgao(Pdata, g>>(32-6)); 
	vgao(Pdata, b>>(32-6)); 
	unlock(&cursor); 
 
	return ~0; 
1993/1113    
} 
 
void 
screenload(Rectangle r, uchar *data, int tl, int l) 
1997/1101    
int 
cursoron(int dolock) 
1993/1113    
{ 
	USED(r, data, tl, l); 
1997/1101    
	VGAscr *scr; 
	int v; 
 
	scr = &vgascreen[0]; 
	if(scr->cur == nil || scr->cur->move == nil) 
		return 0; 
 
	if(dolock) 
		lock(&cursor); 
	v = scr->cur->move(scr, mousexy()); 
	if(dolock) 
		unlock(&cursor); 
 
	return v; 
1993/1113    
} 
 
void 
getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) 
1997/1101    
cursoroff(int) 
1993/1113    
{ 
	p &= (1<<(1<<gscreen.ldepth))-1; 
	lock(&vgalock); 
	*pr = colormap[p][0]; 
	*pg = colormap[p][1]; 
	*pb = colormap[p][2]; 
	unlock(&vgalock); 
} 
 
void 
mousescreenupdate(void) 
1997/1101    
setcursor(Cursor* curs) 
1993/1113    
{ 
} 
1997/1101    
	VGAscr *scr; 
1993/1113    
 
/* 
 *  a fatter than usual cursor for the safari 
 */ 
Cursor fatarrow = { 
	{ -1, -1 }, 
	{ 
		0xff, 0xff, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0c,  
		0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,  
		0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8c, 0x04,  
		0x92, 0x08, 0x91, 0x10, 0xa0, 0xa0, 0xc0, 0x40,  
	}, 
	{ 
		0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfc, 0x7f, 0xf0,  
		0x7f, 0xe0, 0x7f, 0xe0, 0x7f, 0xf0, 0x7f, 0xf8,  
		0x7f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfc, 0x73, 0xf8,  
		0x61, 0xf0, 0x60, 0xe0, 0x40, 0x40, 0x00, 0x00,  
	}, 
}; 
1997/1101    
	scr = &vgascreen[0]; 
	if(scr->cur == nil || scr->cur->load == nil) 
		return; 
1993/1113    
 
void 
bigcursor(void) 
{ 
	memmove(&arrow, &fatarrow, sizeof(fatarrow)); 
	pixreverse(arrow.set, 2*16, 0); 
	pixreverse(arrow.clr, 2*16, 0); 
1997/1101    
	scr->cur->load(scr, curs); 
1993/1113    
} 
1997/1101/sys/src/9/pc/screen.c:117,1231998/0109/sys/src/9/pc/screen.c:117,123 (short | long)
Add softscreen parameter to attachscreen.
rsc Fri Mar 4 12:44:25 2005
1993/1113    
} 
 
1997/1101    
ulong* 
attachscreen(Rectangle* r, int* ld, int* width) 
1998/0109    
attachscreen(Rectangle* r, int* ld, int* width, int *softscreen) 
1993/1113    
{ 
1997/1101    
	VGAscr *scr; 
 
1997/1101/sys/src/9/pc/screen.c:128,1331998/0109/sys/src/9/pc/screen.c:128,134
1997/1101    
	*r = scr->gscreen->r; 
	*ld = scr->gscreen->ldepth; 
	*width = scr->gscreen->width; 
1998/0109    
	*softscreen = scr->useflush; 
1997/1101    
 
	return scr->gscreendata->data; 
1993/1113    
} 
1998/0109/sys/src/9/pc/screen.c:35,401998/0209/sys/src/9/pc/screen.c:35,54 (short | long)
Add arrow Cursor.
rsc Fri Mar 4 12:44:25 2005
1993/1113    
 
1997/1101    
VGAscr vgascreen[1]; 
1993/1113    
 
1998/0209    
Cursor	arrow = { 
	{ -1, -1 }, 
	{ 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,  
	  0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,  
	  0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,  
	  0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,  
	}, 
	{ 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,  
	  0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,  
	  0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,  
	  0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,  
	}, 
}; 
 
1997/1101    
int 
screensize(int x, int y, int z) 
1993/1113    
{ 
1998/0209/sys/src/9/pc/screen.c:10,151999/0119/sys/src/9/pc/screen.c:10,16 (short | long)
Add .
rsc Fri Mar 4 12:44:25 2005
1997/1101    
#define	Image	IMAGE 
#include <draw.h> 
#include <memdraw.h> 
1999/0119    
#include <cursor.h> 
1993/1113    
#include "screen.h" 
 
1997/1101    
static ulong onesbits = ~0; 
1999/0119/sys/src/9/pc/screen.c:13,381999/1005/sys/src/9/pc/screen.c:13,26 (short | long)
1999/0119    
#include <cursor.h> 
1993/1113    
#include "screen.h" 
 
1997/1101    
static ulong onesbits = ~0; 
static Memdata onesdata = { 
	nil, 
	&onesbits, 
1993/1113    
}; 
1997/1101    
static Memimage xones = { 
	{ 0, 0, 1, 1 }, 
	{ -100000, -100000, 100000, 100000 }, 
	3, 
	1, 
	&onesdata, 
	0, 
	1 
1993/1113    
}; 
1997/1101    
Memimage *memones = &xones; 
1999/1005    
#define RGB2K(r,g,b)	((156763*(r)+307758*(g)+59769*(b))>>19) 
1993/1113    
 
1997/1101    
Point ZP = {0, 0}; 
1993/1113    
 
1999/1005    
Rectangle physgscreenr; 
 
1997/1101    
Memdata gscreendata; 
Memimage gscreen; 
1999/1005    
Memimage *gscreen; 
1993/1113    
 
1997/1101    
VGAscr vgascreen[1]; 
1993/1113    
 
1999/0119/sys/src/9/pc/screen.c:51,601999/1005/sys/src/9/pc/screen.c:39,49
1998/0209    
}; 
 
1997/1101    
int 
screensize(int x, int y, int z) 
1999/1005    
screensize(int x, int y, int z, ulong chan) 
1993/1113    
{ 
1997/1101    
	VGAscr *scr; 
1993/1113    
 
1999/1005    
	memimageinit(); 
1997/1101    
	scr = &vgascreen[0]; 
1993/1113    
 
	/* 
1999/0119/sys/src/9/pc/screen.c:62,971999/1005/sys/src/9/pc/screen.c:51,88
1997/1101    
	 * be given back if aperture is set. 
1993/1113    
	 */ 
1997/1101    
	if(scr->aperture == 0){ 
		int width = (x*(1<<z))/BI2WD; 
1999/1005    
		int width = (x*z)/BI2WD; 
1993/1113    
 
1997/1101    
		gscreendata.data = xalloc(width*BY2WD*y); 
		if(gscreendata.data == 0) 
1999/1005    
		gscreendata.bdata = xalloc(width*BY2WD*y); 
		if(gscreendata.bdata == 0) 
1997/1101    
			error("screensize: vga soft memory"); 
		memset(gscreendata.data, Backgnd, width*BY2WD*y); 
1999/1005    
/*		memset(gscreendata.bdata, 0x72, width*BY2WD*y);	/* not really black */ 
1997/1101    
		scr->useflush = 1; 
1993/1113    
                 
1997/1101    
		scr->aperture = 0xA0000; 
		scr->apsize = 1<<16; 
	} 
	else 
		gscreendata.data = KADDR(scr->aperture); 
1999/1005    
		gscreendata.bdata = KADDR(scr->aperture); 
1997/1101    
 
	gscreen.data = &gscreendata; 
	gscreen.ldepth = z; 
	gscreen.width = (x*(1<<gscreen.ldepth)+31)/32; 
	gscreen.r.min = ZP; 
	gscreen.r.max = Pt(x, y); 
	gscreen.clipr = gscreen.r; 
	gscreen.repl = 0; 
1999/1005    
	if(gscreen) 
		freememimage(gscreen); 
1997/1101    
 
	scr->gscreendata = gscreen.data; 
	scr->memdefont = getmemdefont(); 
	scr->gscreen = &gscreen; 
1999/1005    
	gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata); 
	vgaimageinit(chan); 
	if(gscreen == nil) 
		return -1; 
1997/1101    
 
//	memset(gscreen.data->data, Backgnd, scr->apsize); 
1999/1005    
/*	memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8);	/* RSC BUG */ 
	memfillcolor(gscreen, DRed); 
1997/1101    
 
	drawcmap(0); 
1999/1005    
	scr->palettedepth = 6;	/* default */ 
	scr->gscreendata = &gscreendata; 
	scr->memdefont = getmemdefont(); 
	scr->gscreen = gscreen; 
1997/1101    
 
1999/1005    
	physgscreenr = gscreen->r; 
 
	drawcmap(1); 
1997/1101    
	return 0; 
1993/1113    
} 
 
1999/0119/sys/src/9/pc/screen.c:114,1211999/1005/sys/src/9/pc/screen.c:105,111
1997/1101    
		aperture = scr->dev->linear(scr, &size, &align); 
		if(aperture == 0) 
			return 1; 
1993/1113    
	} 
1997/1101    
	else{ 
1999/1005    
	}else{ 
1997/1101    
		aperture = upamalloc(0, size, align); 
		if(aperture == 0) 
			return 1; 
1999/0119/sys/src/9/pc/screen.c:131,1381999/1005/sys/src/9/pc/screen.c:121,128
1997/1101    
	return 0; 
1993/1113    
} 
 
1997/1101    
ulong* 
1998/0109    
attachscreen(Rectangle* r, int* ld, int* width, int *softscreen) 
1999/1005    
uchar* 
attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen) 
1993/1113    
{ 
1997/1101    
	VGAscr *scr; 
 
1999/0119/sys/src/9/pc/screen.c:141,1531999/1005/sys/src/9/pc/screen.c:131,147
1997/1101    
		return nil; 
 
	*r = scr->gscreen->r; 
	*ld = scr->gscreen->ldepth; 
1999/1005    
	*chan = scr->gscreen->chan; 
	*d = scr->gscreen->depth; 
1997/1101    
	*width = scr->gscreen->width; 
1998/0109    
	*softscreen = scr->useflush; 
1997/1101    
 
	return scr->gscreendata->data; 
1999/1005    
	return scr->gscreendata->bdata; 
1993/1113    
} 
 
1999/1005    
/* 
 * It would be fair to say that this doesn't work for >8-bit screens. 
 */ 
1993/1113    
void 
1997/1101    
flushmemscreen(Rectangle r) 
1993/1113    
{ 
1999/0119/sys/src/9/pc/screen.c:166,1771999/1005/sys/src/9/pc/screen.c:160,171
1997/1101    
 
	incs = scr->gscreen->width * BY2WD; 
 
	switch(scr->gscreen->ldepth){ 
1999/1005    
	switch(scr->gscreen->depth){ 
1997/1101    
	default: 
		len = 0; 
		panic("flushmemscreen: ldepth\n"); 
1999/1005    
		panic("flushmemscreen: depth\n"); 
1997/1101    
		break; 
	case 3: 
1999/1005    
	case 8: 
1997/1101    
		len = Dx(r); 
		break; 
	} 
1999/0119/sys/src/9/pc/screen.c:178,1841999/1005/sys/src/9/pc/screen.c:172,178
1997/1101    
	if(len < 1) 
		return; 
 
	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x>>(3-scr->gscreen->ldepth)); 
1999/1005    
	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8; 
1997/1101    
	page = off/scr->apsize; 
	off %= scr->apsize; 
	disp = KADDR(scr->aperture); 
1999/0119/sys/src/9/pc/screen.c:185,1931999/1005/sys/src/9/pc/screen.c:179,188
1997/1101    
	sdisp = disp+off; 
	edisp = disp+scr->apsize; 
 
	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x>>(3-scr->gscreen->ldepth)); 
	sp = ((uchar*)scr->gscreendata->data) + off; 
1999/1005    
	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8; 
1997/1101    
 
1999/1005    
	sp = scr->gscreendata->bdata + off; 
 
1997/1101    
	scr->dev->page(scr, page); 
	for(y = r.min.y; y < r.max.y; y++) { 
		if(sdisp + incs < edisp) { 
1999/0119/sys/src/9/pc/screen.c:225,2351999/1005/sys/src/9/pc/screen.c:220,230
1997/1101    
	if(scr->gscreen == nil) 
		return; 
 
	switch(scr->gscreen->ldepth){ 
1999/1005    
	switch(scr->gscreen->depth){ 
1997/1101    
	default: 
		x = 0x0F; 
		break; 
	case 3: 
1999/1005    
	case 8: 
1997/1101    
		x = 0xFF; 
		break; 
	} 
1999/0119/sys/src/9/pc/screen.c:244,2801999/1005/sys/src/9/pc/screen.c:239,296
1993/1113    
} 
 
1997/1101    
int 
1999/1005    
setpalette(ulong p, ulong r, ulong g, ulong b) 
{ 
	VGAscr *scr; 
	int d; 
 
	scr = &vgascreen[0]; 
	d = scr->palettedepth; 
 
	lock(&cursor); 
	scr->colormap[p][0] = r; 
	scr->colormap[p][1] = g; 
	scr->colormap[p][2] = b; 
	vgao(PaddrW, p); 
	vgao(Pdata, r>>(32-d)); 
	vgao(Pdata, g>>(32-d)); 
	vgao(Pdata, b>>(32-d)); 
	unlock(&cursor); 
 
	return ~0; 
} 
 
/* 
 * On some video cards (e.g. Mach64), the palette is used as the  
 * DAC registers for >8-bit modes.  We don't want to set them when the user 
 * is trying to set a colormap and the card is in one of these modes. 
 */ 
int 
1997/1101    
setcolor(ulong p, ulong r, ulong g, ulong b) 
1993/1113    
{ 
1997/1101    
	VGAscr *scr; 
	ulong x; 
1999/1005    
	int x; 
1997/1101    
 
	scr = &vgascreen[0]; 
	if(scr->gscreen == nil) 
		return 0; 
 
	switch(scr->gscreen->ldepth){ 
	default: 
1999/1005    
	switch(scr->gscreen->depth){ 
	case 1: 
	case 2: 
	case 4: 
1997/1101    
		x = 0x0F; 
		break; 
	case 3: 
1999/1005    
	case 8: 
1997/1101    
		x = 0xFF; 
		break; 
1999/1005    
	default: 
		return 0; 
1997/1101    
	} 
	p &= x; 
	p ^= x; 
 
	lock(&cursor); 
	scr->colormap[p][0] = r; 
	scr->colormap[p][1] = g; 
	scr->colormap[p][2] = b; 
	vgao(PaddrW, p); 
	vgao(Pdata, r>>(32-6)); 
	vgao(Pdata, g>>(32-6)); 
	vgao(Pdata, b>>(32-6)); 
	unlock(&cursor); 
                 
	return ~0; 
1999/1005    
	return setpalette(p, r, g, b); 
1993/1113    
} 
 
1997/1101    
int 
1999/0119/sys/src/9/pc/screen.c:312,3141999/1005/sys/src/9/pc/screen.c:328,517
1993/1113    
 
1997/1101    
	scr->cur->load(scr, curs); 
1993/1113    
} 
1999/1005    
 
static ulong 
pixelbits(Memimage *i, Point pt) 
{ 
	uchar *p; 
	ulong val; 
	int off, bpp, npack; 
 
	val = 0; 
	p = byteaddr(i, pt); 
	switch(bpp=i->depth){ 
	case 1: 
	case 2: 
	case 4: 
		npack = 8/bpp; 
		off = pt.x%npack; 
		val = p[0] >> bpp*(npack-1-off); 
		val &= (1<<bpp)-1; 
		break; 
	case 8: 
		val = p[0]; 
		break; 
	case 16: 
		val = p[0]|(p[1]<<8); 
		break; 
	case 24: 
		val = p[0]|(p[1]<<8)|(p[2]<<16); 
		break; 
	case 32: 
		val = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24); 
		break; 
	} 
	while(bpp<32){ 
		val |= val<<bpp; 
		bpp *= 2; 
	} 
	return val; 
} 
 
 
static ulong 
imgtorgba(Memimage *img, ulong val) 
{ 
	uchar r, g, b, a; 
	int nb, ov, v; 
	ulong chan; 
	uchar *p; 
 
	a = 0xFF; 
	r = g = b = 0xAA;	/* garbage */ 
	for(chan=img->chan; chan; chan>>=8){ 
		nb = NBITS(chan); 
		ov = v = val&((1<<nb)-1); 
		val >>= nb; 
 
		while(nb < 8){ 
			v |= v<<nb; 
			nb *= 2; 
		} 
		v >>= (nb-8); 
 
		switch(TYPE(chan)){ 
		case CRed: 
			r = v; 
			break; 
		case CGreen: 
			g = v; 
			break; 
		case CBlue: 
			b = v; 
			break; 
		case CAlpha: 
			a = v; 
			break; 
		case CGrey: 
			r = g = b = v; 
			break; 
		case CMap: 
			p = img->cmap->cmap2rgb+3*ov; 
			r = *p++; 
			g = *p++;	 
			b = *p; 
			break; 
		} 
	} 
	return (r<<24)|(g<<16)|(b<<8)|a;	 
} 
 
static ulong 
rgbatoimg(Memimage *img, ulong rgba) 
{ 
	ulong chan; 
	int d, nb; 
	ulong v; 
	uchar *p, r, g, b, a, m; 
 
	v = 0; 
	r = rgba>>24; 
	g = rgba>>16; 
	b = rgba>>8; 
	a = rgba; 
	d = 0; 
	for(chan=img->chan; chan; chan>>=8){ 
		nb = NBITS(chan); 
		switch(TYPE(chan)){ 
		case CRed: 
			v |= (r>>(8-nb))<<d; 
			break; 
		case CGreen: 
			v |= (g>>(8-nb))<<d; 
			break; 
		case CBlue: 
			v |= (b>>(8-nb))<<d; 
			break; 
		case CAlpha: 
			v |= (a>>(8-nb))<<d; 
			break; 
		case CMap: 
			p = img->cmap->rgb2cmap; 
			m = p[(r>>4)*256+(g>>4)*16+(b>>4)]; 
			v |= m<<d; 
			break; 
		case CGrey: 
			m = RGB2K(r,g,b); 
			v |= m<<d; 
			break; 
		} 
		d += nb; 
	} 
//	print("rgba2img %.8lux = %.*lux\n", rgba, 2*d/8, v); 
	return v; 
} 
 
Memimage *lastbadi; 
Memdata *lastbad; 
Memimage *lastbadsrc, *lastbaddst; 
 
#ifndef SDFSDF 
int 
hwdraw(Memdrawparam *par) 
{ 
	VGAscr *scr; 
	Memimage *dst, *src; 
 
	dst = par->dst; 
	scr = &vgascreen[0]; 
	if(dst == nil || dst->data == nil) 
		return 0; 
 
	if(dst->data->bdata != gscreendata.bdata) 
		return 0; 
 
//	if(dst->data != &gscreendata){ 
//		lastbad = dst->data; 
//		lastbadi = dst; 
//		return 0; 
//	} 
 
	if(scr->fill==nil && scr->scroll==nil) 
		return 0; 
 
	/* 
	 * If we have an opaque mask and source is one opaque pixel we can convert to the 
	 * destination format and just replicate with memset. 
	 */ 
	if(scr->fill && (par->state&(Simplemask|Simplesrc|Fullmask))==(Simplemask|Simplesrc|Fullmask)) 
		return scr->fill(scr, par->r, par->sdval); 
 
	/* 
	 * If no source alpha, an opaque mask, we can just copy the 
	 * source onto the destination.  If the channels are the same and 
	 * the source is not replicated, memmove suffices. 
	 */ 
	src = par->src; 
	if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha) 
	&& (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){ 
		if(src->zero != dst->zero){ 
			lastbadsrc = src; 
			lastbaddst = dst; 
			iprint("#"); 
		} 
		return scr->scroll(scr, par->r, par->sr); 
	} 
 
	return 0;	 
} 
#endif 
1999/1005/sys/src/9/pc/screen.c:464,4711999/1006/sys/src/9/pc/screen.c:464,471 (short | long)
1999/1005    
Memimage *lastbadi; 
Memdata *lastbad; 
Memimage *lastbadsrc, *lastbaddst; 
1999/1006    
int hwaccel = 1; 
1999/1005    
 
#ifndef SDFSDF 
int 
hwdraw(Memdrawparam *par) 
{ 
1999/1005/sys/src/9/pc/screen.c:472,4771999/1006/sys/src/9/pc/screen.c:472,480
1999/1005    
	VGAscr *scr; 
	Memimage *dst, *src; 
 
1999/1006    
	if(hwaccel == 0) 
		return 0; 
 
1999/1005    
	dst = par->dst; 
	scr = &vgascreen[0]; 
	if(dst == nil || dst->data == nil) 
1999/1005/sys/src/9/pc/screen.c:514,5171999/1006/sys/src/9/pc/screen.c:517,519
1999/1005    
 
	return 0;	 
} 
#endif 
1999/1006/sys/src/9/pc/screen.c:82,881999/1013/sys/src/9/pc/screen.c:82,88 (short | long)
1997/1101    
 
1999/1005    
	physgscreenr = gscreen->r; 
 
	drawcmap(1); 
1999/1013    
	drawcmap(); 
1997/1101    
	return 0; 
1993/1113    
} 
 
1999/1006/sys/src/9/pc/screen.c:288,2941999/1013/sys/src/9/pc/screen.c:288,293
1999/1005    
		return 0; 
1997/1101    
	} 
	p &= x; 
	p ^= x; 
 
1999/1005    
	return setpalette(p, r, g, b); 
1993/1113    
} 
1999/1013/sys/src/9/pc/screen.c:229,2351999/1014/sys/src/9/pc/screen.c:229,234 (short | long)
1997/1101    
		break; 
	} 
	p &= x; 
	p ^= x; 
 
	lock(&cursor); 
	*pr = scr->colormap[p][0]; 
1999/1014/sys/src/9/pc/screen.c:491,4981999/1127/sys/src/9/pc/screen.c:491,499 (short | long)
1999/1005    
		return 0; 
 
	/* 
	 * If we have an opaque mask and source is one opaque pixel we can convert to the 
	 * destination format and just replicate with memset. 
1999/1127    
	 * If we have an opaque mask and source is one opaque 
	 * pixel we can convert to the destination format and just 
	 * replicate with memset. 
1999/1005    
	 */ 
	if(scr->fill && (par->state&(Simplemask|Simplesrc|Fullmask))==(Simplemask|Simplesrc|Fullmask)) 
		return scr->fill(scr, par->r, par->sdval); 
1999/1014/sys/src/9/pc/screen.c:505,5151999/1127/sys/src/9/pc/screen.c:506,516
1999/1005    
	src = par->src; 
	if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha) 
	&& (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){ 
		if(src->zero != dst->zero){ 
			lastbadsrc = src; 
			lastbaddst = dst; 
			iprint("#"); 
		} 
1999/1127    
//		if(src->zero != dst->zero){ 
//			lastbadsrc = src; 
//			lastbaddst = dst; 
//			iprint("#"); 
//		} 
1999/1005    
		return scr->scroll(scr, par->r, par->sr); 
	} 
 
1999/1127/sys/src/9/pc/screen.c:463,4682000/0326/sys/src/9/pc/screen.c:463,469 (short | long)
1999/1005    
Memdata *lastbad; 
Memimage *lastbadsrc, *lastbaddst; 
1999/1006    
int hwaccel = 1; 
2000/0326    
int hwblank = 1; 
1999/1005    
 
int 
hwdraw(Memdrawparam *par) 
1999/1127/sys/src/9/pc/screen.c:515,5182000/0326/sys/src/9/pc/screen.c:516,529
1999/1005    
	} 
 
	return 0;	 
2000/0326    
} 
 
void 
blankscreen(int blank) 
{ 
	VGAscr *scr; 
 
	scr = &vgascreen[0]; 
	if(hwblank && scr->blank) 
		scr->blank(scr, blank); 
1999/1005    
} 
2000/0326/sys/src/9/pc/screen.c:470,4752000/0711/sys/src/9/pc/screen.c:470,476 (short | long)
1999/1005    
{ 
	VGAscr *scr; 
	Memimage *dst, *src; 
2000/0711    
	int m; 
1999/1005    
 
1999/1006    
	if(hwaccel == 0) 
		return 0; 
2000/0326/sys/src/9/pc/screen.c:496,5022000/0711/sys/src/9/pc/screen.c:497,504
1999/1127    
	 * pixel we can convert to the destination format and just 
	 * replicate with memset. 
1999/1005    
	 */ 
	if(scr->fill && (par->state&(Simplemask|Simplesrc|Fullmask))==(Simplemask|Simplesrc|Fullmask)) 
2000/0711    
	m = Simplesrc|Simplemask|Fullmask; 
	if(scr->fill && (par->state&m)==m && ((par->srgba&0xFF) == 0xFF)) 
1999/1005    
		return scr->fill(scr, par->r, par->sdval); 
 
	/* 
2000/0711/sys/src/9/pc/screen.c:73,792001/0124/sys/src/9/pc/screen.c:73,79 (short | long)
Turn off debugging memfillcolor.
rsc Fri Mar 4 12:44:25 2005
1999/1005    
		return -1; 
1997/1101    
 
1999/1005    
/*	memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8);	/* RSC BUG */ 
	memfillcolor(gscreen, DRed); 
2001/0124    
//	memfillcolor(gscreen, DRed); 
1997/1101    
 
1999/1005    
	scr->palettedepth = 6;	/* default */ 
	scr->gscreendata = &gscreendata; 
2001/0124/sys/src/9/pc/screen.c:73,792001/0527/sys/src/9/pc/screen.c:73,79 (short | long)
1999/1005    
		return -1; 
1997/1101    
 
1999/1005    
/*	memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8);	/* RSC BUG */ 
2001/0124    
//	memfillcolor(gscreen, DRed); 
2001/0527    
	memfillcolor(gscreen, DRed); 
1997/1101    
 
1999/1005    
	scr->palettedepth = 6;	/* default */ 
	scr->gscreendata = &gscreendata; 
2001/0124/sys/src/9/pc/screen.c:327,4672001/0527/sys/src/9/pc/screen.c:327,332
1997/1101    
	scr->cur->load(scr, curs); 
1993/1113    
} 
1999/1005    
 
static ulong 
pixelbits(Memimage *i, Point pt) 
{ 
	uchar *p; 
	ulong val; 
	int off, bpp, npack; 
                 
	val = 0; 
	p = byteaddr(i, pt); 
	switch(bpp=i->depth){ 
	case 1: 
	case 2: 
	case 4: 
		npack = 8/bpp; 
		off = pt.x%npack; 
		val = p[0] >> bpp*(npack-1-off); 
		val &= (1<<bpp)-1; 
		break; 
	case 8: 
		val = p[0]; 
		break; 
	case 16: 
		val = p[0]|(p[1]<<8); 
		break; 
	case 24: 
		val = p[0]|(p[1]<<8)|(p[2]<<16); 
		break; 
	case 32: 
		val = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24); 
		break; 
	} 
	while(bpp<32){ 
		val |= val<<bpp; 
		bpp *= 2; 
	} 
	return val; 
} 
                 
                 
static ulong 
imgtorgba(Memimage *img, ulong val) 
{ 
	uchar r, g, b, a; 
	int nb, ov, v; 
	ulong chan; 
	uchar *p; 
                 
	a = 0xFF; 
	r = g = b = 0xAA;	/* garbage */ 
	for(chan=img->chan; chan; chan>>=8){ 
		nb = NBITS(chan); 
		ov = v = val&((1<<nb)-1); 
		val >>= nb; 
                 
		while(nb < 8){ 
			v |= v<<nb; 
			nb *= 2; 
		} 
		v >>= (nb-8); 
                 
		switch(TYPE(chan)){ 
		case CRed: 
			r = v; 
			break; 
		case CGreen: 
			g = v; 
			break; 
		case CBlue: 
			b = v; 
			break; 
		case CAlpha: 
			a = v; 
			break; 
		case CGrey: 
			r = g = b = v; 
			break; 
		case CMap: 
			p = img->cmap->cmap2rgb+3*ov; 
			r = *p++; 
			g = *p++;	 
			b = *p; 
			break; 
		} 
	} 
	return (r<<24)|(g<<16)|(b<<8)|a;	 
} 
                 
static ulong 
rgbatoimg(Memimage *img, ulong rgba) 
{ 
	ulong chan; 
	int d, nb; 
	ulong v; 
	uchar *p, r, g, b, a, m; 
                 
	v = 0; 
	r = rgba>>24; 
	g = rgba>>16; 
	b = rgba>>8; 
	a = rgba; 
	d = 0; 
	for(chan=img->chan; chan; chan>>=8){ 
		nb = NBITS(chan); 
		switch(TYPE(chan)){ 
		case CRed: 
			v |= (r>>(8-nb))<<d; 
			break; 
		case CGreen: 
			v |= (g>>(8-nb))<<d; 
			break; 
		case CBlue: 
			v |= (b>>(8-nb))<<d; 
			break; 
		case CAlpha: 
			v |= (a>>(8-nb))<<d; 
			break; 
		case CMap: 
			p = img->cmap->rgb2cmap; 
			m = p[(r>>4)*256+(g>>4)*16+(b>>4)]; 
			v |= m<<d; 
			break; 
		case CGrey: 
			m = RGB2K(r,g,b); 
			v |= m<<d; 
			break; 
		} 
		d += nb; 
	} 
//	print("rgba2img %.8lux = %.*lux\n", rgba, 2*d/8, v); 
	return v; 
} 
                 
Memimage *lastbadi; 
Memdata *lastbad; 
Memimage *lastbadsrc, *lastbaddst; 
1999/1006    
int hwaccel = 1; 
2000/0326    
int hwblank = 1; 
1999/1005    
 
2001/0124/sys/src/9/pc/screen.c:483,4942001/0527/sys/src/9/pc/screen.c:348,353
1999/1005    
	if(dst->data->bdata != gscreendata.bdata) 
		return 0; 
 
//	if(dst->data != &gscreendata){ 
//		lastbad = dst->data; 
//		lastbadi = dst; 
//		return 0; 
//	} 
                 
	if(scr->fill==nil && scr->scroll==nil) 
		return 0; 
 
2001/0124/sys/src/9/pc/screen.c:509,5192001/0527/sys/src/9/pc/screen.c:368,373
1999/1005    
	src = par->src; 
	if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha) 
	&& (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){ 
1999/1127    
//		if(src->zero != dst->zero){ 
//			lastbadsrc = src; 
//			lastbaddst = dst; 
//			iprint("#"); 
//		} 
1999/1005    
		return scr->scroll(scr, par->r, par->sr); 
	} 
 
2001/0527/sys/src/9/pc/screen.c:72,802001/0822/sys/src/9/pc/screen.c:72,77 (short | long)
1999/1005    
	if(gscreen == nil) 
		return -1; 
1997/1101    
 
1999/1005    
/*	memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8);	/* RSC BUG */ 
2001/0527    
	memfillcolor(gscreen, DRed); 
1997/1101    
                 
1999/1005    
	scr->palettedepth = 6;	/* default */ 
	scr->gscreendata = &gscreendata; 
	scr->memdefont = getmemdefont(); 
2001/0822/sys/src/9/pc/screen.c:13,182001/1014/sys/src/9/pc/screen.c:13,20 (short | long)
1999/0119    
#include <cursor.h> 
1993/1113    
#include "screen.h" 
 
2001/1014    
#define round16(x) (((x)+15)&~15) 
 
1999/1005    
#define RGB2K(r,g,b)	((156763*(r)+307758*(g)+59769*(b))>>19) 
1993/1113    
 
1997/1101    
Point ZP = {0, 0}; 
2001/0822/sys/src/9/pc/screen.c:51,572001/1014/sys/src/9/pc/screen.c:53,59
1997/1101    
	 * be given back if aperture is set. 
1993/1113    
	 */ 
1997/1101    
	if(scr->aperture == 0){ 
1999/1005    
		int width = (x*z)/BI2WD; 
2001/1014    
		int width = (round16(x)*z)/BI2WD; 
1993/1113    
 
1999/1005    
		gscreendata.bdata = xalloc(width*BY2WD*y); 
		if(gscreendata.bdata == 0) 
2001/0822/sys/src/9/pc/screen.c:67,762001/1014/sys/src/9/pc/screen.c:69,80
1999/1005    
	if(gscreen) 
		freememimage(gscreen); 
1997/1101    
 
1999/1005    
	gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata); 
2001/1014    
	gscreen = allocmemimaged(Rect(0,0,round16(x),y), chan, &gscreendata); 
1999/1005    
	vgaimageinit(chan); 
	if(gscreen == nil) 
		return -1; 
2001/1014    
 
	gscreen->r.max.x = x;	/* we used round16(x) to allocate */ 
1997/1101    
 
1999/1005    
	scr->palettedepth = 6;	/* default */ 
	scr->gscreendata = &gscreendata; 
2001/1014/sys/src/9/pc/screen.c:13,202001/1015/sys/src/9/pc/screen.c:13,18 (short | long)
1999/0119    
#include <cursor.h> 
1993/1113    
#include "screen.h" 
 
2001/1014    
#define round16(x) (((x)+15)&~15) 
                 
1999/1005    
#define RGB2K(r,g,b)	((156763*(r)+307758*(g)+59769*(b))>>19) 
1993/1113    
 
1997/1101    
Point ZP = {0, 0}; 
2001/1014/sys/src/9/pc/screen.c:53,592001/1015/sys/src/9/pc/screen.c:51,57
1997/1101    
	 * be given back if aperture is set. 
1993/1113    
	 */ 
1997/1101    
	if(scr->aperture == 0){ 
2001/1014    
		int width = (round16(x)*z)/BI2WD; 
2001/1015    
		int width = (x*z)/BI2WD; 
1993/1113    
 
1999/1005    
		gscreendata.bdata = xalloc(width*BY2WD*y); 
		if(gscreendata.bdata == 0) 
2001/1014/sys/src/9/pc/screen.c:69,812001/1015/sys/src/9/pc/screen.c:67,77
1999/1005    
	if(gscreen) 
		freememimage(gscreen); 
1997/1101    
 
2001/1014    
	gscreen = allocmemimaged(Rect(0,0,round16(x),y), chan, &gscreendata); 
2001/1015    
	gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata); 
1999/1005    
	vgaimageinit(chan); 
	if(gscreen == nil) 
		return -1; 
2001/1014    
 
	gscreen->r.max.x = x;	/* we used round16(x) to allocate */ 
1997/1101    
                 
1999/1005    
	scr->palettedepth = 6;	/* default */ 
	scr->gscreendata = &gscreendata; 
	scr->memdefont = getmemdefont(); 
2001/1014/sys/src/9/pc/screen.c:131,1372001/1015/sys/src/9/pc/screen.c:127,133
1997/1101    
	if(scr->gscreen == nil || scr->gscreendata == nil) 
		return nil; 
 
	*r = scr->gscreen->r; 
2001/1015    
	*r = scr->gscreen->clipr; 
1999/1005    
	*chan = scr->gscreen->chan; 
	*d = scr->gscreen->depth; 
1997/1101    
	*width = scr->gscreen->width; 
2001/1014/sys/src/9/pc/screen.c:329,3352001/1015/sys/src/9/pc/screen.c:325,332
1993/1113    
} 
1999/1005    
 
1999/1006    
int hwaccel = 1; 
2000/0326    
int hwblank = 1; 
2001/1015    
int hwblank = 0;	/* turned on by drivers that are known good */ 
int panning = 0; 
1999/1005    
 
int 
hwdraw(Memdrawparam *par) 
2001/1015/sys/src/9/pc/screen.c:378,3832001/1130/sys/src/9/pc/screen.c:378,387 (short | long)
2000/0326    
	VGAscr *scr; 
 
	scr = &vgascreen[0]; 
	if(hwblank && scr->blank) 
		scr->blank(scr, blank); 
2001/1130    
	if(hwblank){ 
		if(scr->blank) 
			scr->blank(scr, blank); 
		else 
			vgablank(scr, blank); 
	} 
1999/1005    
} 
2001/1130/sys/src/9/pc/screen.c:72,772002/0404/sys/src/9/pc/screen.c:72,80 (short | long)
1999/1005    
	if(gscreen == nil) 
		return -1; 
2001/1014    
 
2002/0404    
	if(scr->dev && scr->dev->flush) 
		scr->useflush = 1; 
 
1999/1005    
	scr->palettedepth = 6;	/* default */ 
	scr->gscreendata = &gscreendata; 
	scr->memdefont = getmemdefont(); 
2001/1130/sys/src/9/pc/screen.c:147,1522002/0404/sys/src/9/pc/screen.c:150,159
1997/1101    
	int y, len, incs, off, page; 
 
	scr = &vgascreen[0]; 
2002/0404    
	if(scr->dev && scr->dev->flush){ 
		scr->dev->flush(scr, r); 
		return; 
	} 
1997/1101    
	if(scr->gscreen == nil || scr->useflush == 0) 
		return; 
	if(scr->dev == nil || scr->dev->page == nil) 
2002/0404/sys/src/9/pc/screen.c:392,3942002/0919/sys/src/9/pc/screen.c:392,406 (short | long)
2001/1130    
			vgablank(scr, blank); 
	} 
1999/1005    
} 
2002/0919    
 
void 
screensignal(int x) 
{ 
	VGAscr *scr; 
 
	scr = &vgascreen[0]; 
	if(scr->aperture == 0) 
		return; 
 
	memset(scr->aperture, x, 8*1024); 
} 
2002/0919/sys/src/9/pc/screen.c:392,4062002/0920/sys/src/9/pc/screen.c:392,394 (short | long)
2001/1130    
			vgablank(scr, blank); 
	} 
1999/1005    
} 
2002/0919    
                 
void 
screensignal(int x) 
{ 
	VGAscr *scr; 
                 
	scr = &vgascreen[0]; 
	if(scr->aperture == 0) 
		return; 
                 
	memset(scr->aperture, x, 8*1024); 
} 
2002/0920/sys/src/9/pc/screen.c:385,3902002/1201/sys/src/9/pc/screen.c:385,391 (short | long)
2000/0326    
	VGAscr *scr; 
 
	scr = &vgascreen[0]; 
2002/1201    
	scr->isblank = blank; 
2001/1130    
	if(hwblank){ 
		if(scr->blank) 
			scr->blank(scr, blank); 
2002/1201/sys/src/9/pc/screen.c:58,642002/1205/sys/src/9/pc/screen.c:58,64 (short | long)
1997/1101    
			error("screensize: vga soft memory"); 
1999/1005    
/*		memset(gscreendata.bdata, 0x72, width*BY2WD*y);	/* not really black */ 
1997/1101    
		scr->useflush = 1; 
		scr->aperture = 0xA0000; 
2002/1205    
		scr->aperture = VGAMEM(); 
1997/1101    
		scr->apsize = 1<<16; 
	} 
	else 
2002/1201/sys/src/9/pc/screen.c:362,3682002/1205/sys/src/9/pc/screen.c:362,371
1999/1127    
	 * replicate with memset. 
1999/1005    
	 */ 
2000/0711    
	m = Simplesrc|Simplemask|Fullmask; 
	if(scr->fill && (par->state&m)==m && ((par->srgba&0xFF) == 0xFF)) 
2002/1205    
	if(scr->fill 
	&& (par->state&m)==m 
	&& ((par->srgba&0xFF) == 0xFF) 
	&& (par->op&S) == S) 
1999/1005    
		return scr->fill(scr, par->r, par->sdval); 
 
	/* 
2002/1201/sys/src/9/pc/screen.c:370,3802002/1205/sys/src/9/pc/screen.c:373,386
1999/1005    
	 * source onto the destination.  If the channels are the same and 
	 * the source is not replicated, memmove suffices. 
	 */ 
2002/1205    
	m = Simplemask|Fullmask; 
1999/1005    
	src = par->src; 
	if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha) 
	&& (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){ 
2002/1205    
	if(scr->scroll 
	&& src->data->bdata==dst->data->bdata 
	&& !(src->flags&Falpha) 
	&& (par->state&m)==m 
	&& (par->op&S) == S) 
1999/1005    
		return scr->scroll(scr, par->r, par->sr); 
	} 
 
	return 0;	 
2000/0326    
} 
2002/1201/sys/src/9/pc/screen.c:385,3912002/1205/sys/src/9/pc/screen.c:391,396
2000/0326    
	VGAscr *scr; 
 
	scr = &vgascreen[0]; 
2002/1201    
	scr->isblank = blank; 
2001/1130    
	if(hwblank){ 
		if(scr->blank) 
			scr->blank(scr, blank); 


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