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

2000/0407/alphapc/vga.c (diff list | history)

2000/0407/sys/src/9/alphapc/vga.c:1,2192000/1102/sys/src/9/alphapc/vga.c:1,225 (short | long | prev | next)
1999/0415    
#include "u.h" 
#include "../port/lib.h" 
#include "mem.h" 
#include "dat.h" 
#include "fns.h" 
#include "../port/error.h" 
 
#define	Image	IMAGE 
#include <draw.h> 
#include <memdraw.h> 
#include <cursor.h> 
#include "screen.h" 
 
2000/0401    
static Memimage* back; 
static Memimage *conscol; 
1999/0415    
 
static Point curpos; 
static Rectangle window; 
static int *xp; 
static int xbuf[256]; 
static Lock vgascreenlock; 
2000/0401    
int drawdebug; 
1999/0415    
 
2000/0401    
void 
vgaimageinit(ulong chan) 
{ 
	if(back == nil){ 
		back = allocmemimage(Rect(0,0,1,1), chan);	/* RSC BUG */ 
		if(back == nil) 
			panic("back alloc");		/* RSC BUG */ 
		back->flags |= Frepl; 
		back->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); 
		memfillcolor(back, DBlack); 
	} 
 
	if(conscol == nil){ 
		conscol = allocmemimage(Rect(0,0,1,1), chan);	/* RSC BUG */ 
		if(conscol == nil) 
			panic("conscol alloc");	/* RSC BUG */ 
		conscol->flags |= Frepl; 
		conscol->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); 
		memfillcolor(conscol, DWhite); 
	} 
} 
 
1999/0415    
static void 
vgascroll(VGAscr* scr) 
{ 
	int h, o; 
	Point p; 
	Rectangle r; 
 
	h = scr->memdefont->height; 
	o = 8*h; 
	r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); 
	p = Pt(window.min.x, window.min.y+o); 
2000/0401    
	memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p); 
1999/0415    
	r = Rpt(Pt(window.min.x, window.max.y-o), window.max); 
2000/0401    
	memimagedraw(scr->gscreen, r, back, ZP, nil, ZP); 
1999/0415    
 
	curpos.y -= o; 
} 
 
static void 
vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr) 
{ 
	Point p; 
	int h, w, pos; 
	Rectangle r; 
 
2000/0401    
//	drawdebug = 1; 
1999/0415    
	if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) 
		xp = xbuf; 
 
	h = scr->memdefont->height; 
	switch(buf[0]){ 
 
	case '\n': 
		if(curpos.y+h >= window.max.y){ 
			vgascroll(scr); 
			*flushr = window; 
		} 
		curpos.y += h; 
		vgascreenputc(scr, "\r", flushr); 
		break; 
 
	case '\r': 
		xp = xbuf; 
		curpos.x = window.min.x; 
		break; 
 
	case '\t': 
		p = memsubfontwidth(scr->memdefont, " "); 
		w = p.x; 
		*xp++ = curpos.x; 
2000/1102    
		if(curpos.x >= window.max.x-4*w) 
			vgascreenputc(scr, "\n", flushr); 
 
1999/0415    
		pos = (curpos.x-window.min.x)/w; 
		pos = 4-(pos%4); 
2000/1102    
		*xp++ = curpos.x; 
1999/0415    
		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y+h); 
2000/0401    
		memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP); 
		combinerect(flushr, r); 
1999/0415    
		curpos.x += pos*w; 
		break; 
 
	case '\b': 
		if(xp <= xbuf) 
			break; 
		xp--; 
		r = Rect(*xp, curpos.y, curpos.x, curpos.y+h); 
2000/0401    
		memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP); 
		combinerect(flushr, r); 
1999/0415    
		curpos.x = *xp; 
2000/1102    
		break; 
 
	case '\0': 
1999/0415    
		break; 
 
	default: 
		p = memsubfontwidth(scr->memdefont, buf); 
		w = p.x; 
 
		if(curpos.x >= window.max.x-w) 
			vgascreenputc(scr, "\n", flushr); 
 
		*xp++ = curpos.x; 
		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h); 
2000/0401    
		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min); 
		memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf); 
		combinerect(flushr, r); 
1999/0415    
		curpos.x += w; 
	} 
2000/0401    
//	drawdebug = 0; 
1999/0415    
} 
 
static void 
vgascreenputs(char* s, int n) 
{ 
	int i; 
	Rune r; 
	char buf[4]; 
	VGAscr *scr; 
	Rectangle flushr; 
 
	scr = &vgascreen[0]; 
 
	if(!islo()){ 
		/* 
		 * Don't deadlock trying to 
		 * print in an interrupt. 
		 */ 
		if(!canlock(&vgascreenlock)) 
			return; 
	} 
	else 
		lock(&vgascreenlock); 
 
	flushr = Rect(10000, 10000, -10000, -10000); 
 
	while(n > 0){ 
		i = chartorune(&r, s); 
		if(i == 0){ 
			s++; 
			--n; 
			continue; 
		} 
		memmove(buf, s, i); 
		buf[i] = 0; 
		n -= i; 
		s += i; 
		vgascreenputc(scr, buf, &flushr); 
	} 
	flushmemscreen(flushr); 
 
	unlock(&vgascreenlock); 
} 
 
void 
vgascreenwin(VGAscr* scr) 
{ 
	int h, w; 
 
	h = scr->memdefont->height; 
	w = scr->memdefont->info[' '].width; 
 
	window.min = Pt(48, 48); 
	window.max = addpt(window.min, Pt(10+w*80, 10+h*50)); 
	if(window.max.y >= scr->gscreen->r.max.y) 
		window.max.y = scr->gscreen->r.max.y-1; 
	if(window.max.x >= scr->gscreen->r.max.x) 
		window.max.x = scr->gscreen->r.max.x-1; 
	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; 
	curpos = window.min; 
 
	screenputs = vgascreenputs; 
} 
2000/0407    
 
/* 
 * Supposedly this is the way to turn DPMS 
 * monitors off using just the VGA registers. 
 * Unfortunately, it seems to mess up the video mode 
 * on the cards I've tried. 
 */ 
void 
vgablank(VGAscr*, int blank) 
{ 
	uchar seq1, crtc17; 
 
	if(blank) { 
		seq1 = 0x00; 
		crtc17 = 0x80; 
	} else { 
		seq1 = 0x20; 
		crtc17 = 0x00; 
	} 
 
	outs(Seqx, 0x0100);			/* synchronous reset */ 
	seq1 |= vgaxi(Seqx, 1) & ~0x20; 
	vgaxo(Seqx, 1, seq1); 
	crtc17 |= vgaxi(Crtx, 0x17) & ~0x80; 
	delay(10); 
	vgaxo(Crtx, 0x17, crtc17); 
	outs(Crtx, 0x0300);				/* end synchronous reset */ 
} 


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