~kris/9p

9hist

17887901fd4052103c5b3491dfce1dd04ff6967a — David du Colombier 32 years ago 093dd92
Plan 9 from Bell Labs 1994-04-14
6 files changed, 252 insertions(+), 246 deletions(-)

M carrera/screen.c
M carrera/screen.h
M pc/devvga.c
A pc/screen.h
M port/devmouse.c
M port/portfns.h
M carrera/screen.c => carrera/screen.c +34 -26
@@ 93,7 93,7 @@ Cursor fatarrow = {
};

static Rectangle window;
static Point cursor;
static Point curpos;
static int h, w;
extern Cursor arrow;



@@ 126,10 126,9 @@ screenwin(void)
	p = add(window.min, Pt(10, 2));
	subfstring(&gscreen, p, &defont0, "Brazil Console ", S);
	window.min.y += h+6;
	cursor = window.min;
	curpos = window.min;
	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;

	hwcurs = 1;
	d = DAC;
	/* cursor color 1: white */
	d->cr1 = 0x01;


@@ 151,7 150,7 @@ screenwin(void)
	d->cr2 = 0;
	/* initialize with all-transparent cursor */
	memset(zbuf, 0, sizeof zbuf);
	hwcursset(zbuf, zbuf, 0, 0);
	setcursor(zbuf, zbuf, 0, 0);
	/* enable both planes of cursor */
	d->cr1 = 0x03;
	d->cr0 = 0x00;


@@ 252,7 251,7 @@ scroll(void)
	bitblt(&gscreen, window.min, &gscreen, r, S);
	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
	bitblt(&gscreen, r.min, &gscreen, r, Zero);
	cursor.y -= o;
	curpos.y -= o;
}

static void


@@ 263,33 262,33 @@ screenputc(char *buf)

	switch(buf[0]) {
	case '\n':
		if(cursor.y+h >= window.max.y)
		if(curpos.y+h >= window.max.y)
			scroll();
		cursor.y += h;
		curpos.y += h;
		screenputc("\r");
		break;
	case '\r':
		cursor.x = window.min.x;
		curpos.x = window.min.x;
		break;
	case '\t':
		pos = (cursor.x-window.min.x)/w;
		pos = (curpos.x-window.min.x)/w;
		pos = 8-(pos%8);
		cursor.x += pos*w;
		curpos.x += pos*w;
		break;
	case '\b':
		if(cursor.x-w >= 0){
			r.min.x = cursor.x-w;
			r.max.x = cursor.x;
			r.min.y = cursor.y;
			r.max.y = cursor.y+defont0.height;
		if(curpos.x-w >= 0){
			r.min.x = curpos.x-w;
			r.max.x = curpos.x;
			r.min.y = curpos.y;
			r.max.y = curpos.y+defont0.height;
			bitblt(&gscreen, r.min, &gscreen, r, Zero);
			cursor.x -= w;
			curpos.x -= w;
		}
		break;
	default:
		if(cursor.x >= window.max.x-w)
		if(curpos.x >= window.max.x-w)
			screenputc("\n");
		cursor = subfstring(&gscreen, cursor, &defont0, buf, S);
		curpos = subfstring(&gscreen, curpos, &defont0, buf, S);
	}
}



@@ 408,7 407,7 @@ rep(ulong v, int n)
}

void
hwcursset(ulong *s, ulong *c, int offx, int offy)
setcursor(ulong *s, ulong *c, int offx, int offy)
{
	Dac *d;
	int x, y;


@@ 453,20 452,29 @@ hwcursset(ulong *s, ulong *c, int offx, int offy)
}

void
hwcursmove(int x, int y)
cursoron(int dolock)
{
	Dac *d;
	Point p;

	p = mousexy();

	d = DAC;

	x += 380;		/* adjusted by experiment */
	y += 11;		/* adjusted by experiment */
	if(dolock)
		lock(&cursor);

	p.x += 380;		/* adjusted by experiment */
	p.y += 11;		/* adjusted by experiment */
	d->cr1 = 03;
	d->cr0 = 01;
	d->cr2 = x&0xFF;
	d->cr2 = (x>>8)&0xF;
	d->cr2 = y&0xFF;
	d->cr2 = (y>>8)&0xF;
	d->cr2 = p.x&0xFF;
	d->cr2 = (p.x>>8)&0xF;
	d->cr2 = p.y&0xFF;
	d->cr2 = (p.y>>8)&0xF;

	if(dolock)
		unlock(&cursor);
}

int

M carrera/screen.h => carrera/screen.h +14 -6
@@ 1,8 1,16 @@
extern void		mouseupdate(int);
typedef struct Cursorinfo	Cursorinfo;

#define	hwscreenwrite(a, b)
struct Cursorinfo
{
	Cursor;
	Lock;
};

#define mbbpt(x)
#define mbbrect(x)
#define mousescreenupdate()
#define mousectl(s)
extern Cursorinfo	cursor;

extern void	mouseupdate(int);
extern void	cursoron(int);
#define		cursoroff(x)
#define		mousectl(s)
extern Point	mousexy(void);
#define		hwscreenwrite(a, b)

M pc/devvga.c => pc/devvga.c +174 -1
@@ 7,6 7,7 @@
#include	"../port/error.h"

#include	<libg.h>
#include	"screen.h"

enum
{


@@ 209,6 210,7 @@ void
vgareset(void)
{
	vgacard = &vgachips[Generic];
	cursor.disable++;
}

void


@@ 219,6 221,7 @@ vgainit(void)
Chan*
vgaattach(char *upec)
{
	print("visible %d disable %d frozen %d\n", cursor.visible, cursor.disable, cursor.frozen);
	return devattach('v', upec);
}



@@ 456,6 459,8 @@ setscreen(int maxx, int maxy, int ldepth)
		error(Ebadarg);
	}

	lock(&screenlock);

	/*
	 *  setup a bitmap for the new size
	 */


@@ 497,13 502,18 @@ setscreen(int maxx, int maxy, int ldepth)

	window.min = Pt(50, 50);
	window.max = add(window.min, Pt(10+w*64, Footprint/(BY2WD*gscreen.width)));
	if(window.max.y >= gscreen.r.max.y)
		window.max.y = gscreen.r.max.y;
	if(window.max.x >= gscreen.r.max.x)
		window.max.x = gscreen.r.max.x;

	vgacard->setpage(0);
	bitblt(&gscreen, window.min, &gscreen, window, Zero);
	window = inset(window, 5);
	curpos = window.min;
	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
	hwcurs = 0;

	cursorinit();
}

/*


@@ 1164,3 1174,166 @@ setcolor(ulong p, ulong r, ulong g, ulong b)
	unlock(&screenlock);
	return ~0;
}


/*
 *  software cursor
 */

ulong backbits[16*5];
ulong workbits[16*5];
Bitmap cursorwork =
{
	{0, 0, 16+8, 16},
	{0, 0, 16+8, 16},
	0,
	workbits,
	0,
	1,
};

Bitmap	clr =
{
	{0, 0, 16, 16},
	{0, 0, 16, 16},
	0,
	0,
	0,
	1,
};

Bitmap	set =
{
	{0, 0, 16, 16},
	{0, 0, 16, 16},
	0,
	0,
	0,
	1,
};

void
cursorinit(void)
{
	static int already;

	lock(&cursor);

	cursorwork.ldepth = gscreen.ldepth;
	cursorwork.width = ((cursorwork.r.max.x << gscreen.ldepth) + 31) >> 5;
	cursor.l = cursorwork.width*BY2WD;

	if(!already){
		cursor.disable--;
		already = 1;
	}

	unlock(&cursor);
}

void
setcursor(ulong *setbits, ulong *clrbits, int offx, int offy)
{
	USED(offx, offy);
	set.base = setbits;
	clr.base = clrbits;
}

void
cursoron(int dolock)
{
	int off;
	Rectangle r;
	uchar *a;
	struct {
		Bitmap *dm;
		Point p;
		Bitmap *sm;
		Rectangle r;
		Fcode f;
	} xx;
	extern int graphicssubtile(uchar*, int, int, Rectangle, Rectangle, uchar**);

	if(cursor.disable)
		return;
	if(dolock)
		lock(&cursor);

	if(cursor.visible++ == 0){
		cursor.r.min = mousexy();
		cursor.r.max = add(cursor.r.min, Pt(16, 16));
		cursor.r = raddp(cursor.r, cursor.offset);
	
		/* bit offset into backup area */
		if(cursor.r.min.x < 0)
			off = cursor.r.min.x;
		else
			off = ((1<<gscreen.ldepth)*cursor.r.min.x) & 7;
	
		/* clip the cursor rectangle */
		xx.dm = &cursorwork;
		xx.p = Pt(off, 0);
		xx.sm = &gscreen;
		xx.r = cursor.r;
		bitbltclip(&xx);
	
		/* tile width */
		cursor.tl = graphicssubtile(0, cursor.l, gscreen.ldepth,
				gscreen.r, xx.r, &a);
		if(cursor.tl > 0){
			/* get tile */
			screenunload(xx.r, (uchar*)workbits, cursor.tl, cursor.l, 0);
	
			/* save for cursoroff */
			memmove(backbits, workbits, cursor.l*16);
	
			/* add mouse into work area */
			r = Rect(0, 0, Dx(xx.r), Dy(xx.r));
			bitblt(&cursorwork, xx.p, &clr, r, S|D);
			bitblt(&cursorwork, xx.p, &set, r, D&~S);
	
			/* put back tile */
			cursor.clipr = xx.r;
			screenload(xx.r, (uchar*)workbits, cursor.tl, cursor.l, 0);
		}
	}

	if(dolock)
		unlock(&cursor);
}

void
cursoroff(int dolock)
{
	if(cursor.disable)
		return;
	if(dolock)
		lock(&cursor);
	if(--cursor.visible == 0 && cursor.tl > 0)
		screenload(cursor.clipr, (uchar*)backbits, cursor.tl, cursor.l, 0);
	if(dolock)
		unlock(&cursor);
}

void
cursorlock(Rectangle r)
{
	lock(&cursor);
	if(rectXrect(cursor.r, r)){
		cursoroff(0);
		cursor.frozen = 1;
	}
	cursor.disable++;
	unlock(&cursor);
}

void
cursorunlock(void)
{
	lock(&cursor);
	cursor.disable--;
	if(cursor.frozen)
		cursoron(0);
	cursor.frozen = 0;
	unlock(&cursor);
}

A pc/screen.h => pc/screen.h +20 -0
@@ 0,0 1,20 @@
typedef struct Cursorinfo	Cursorinfo;

struct Cursorinfo
{
	Cursor;
	Lock;
	int	visible;	/* on screen */
	int	disable;	/* from being used */
	int	frozen;		/* from being used */
	Rectangle r;		/* location */
	Rectangle clipr;	/* r clipped into screen */
	int	l;		/* width of cursorwork (in bytes) */
	int	tl;		/* scan line byte width of mouse at r */
};

Cursorinfo	cursor;
extern void	cursoron(int);
extern void	cursoroff(int);
extern Point	mousexy(void);
extern void	cursorinit(void);

M port/devmouse.c => port/devmouse.c +9 -209
@@ 9,26 9,7 @@
#include	"devtab.h"
#include	"screen.h"

/*
 * Some monochrome screens are reversed from what we like:
 * We want 0's bright and 1's 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? */

typedef struct Mouseinfo	Mouseinfo;
typedef struct Cursorinfo	Cursorinfo;

struct Mouseinfo
{


@@ 48,29 29,12 @@ struct Mouseinfo
	int	open;
};

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

	int	l;
	int	tl;
	int	setop;
	int	clrop;
	Rectangle clipr;
};

Mouseinfo	mouse;
Cursorinfo	cursor;
int		mouseshifted;
int		mousetype;
int		mouseswap;
int		hwcurs;
Cursor	curs;
Cursor		curs;

Cursor	arrow =
{


@@ 88,45 52,11 @@ Cursor	arrow =
};

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

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

ulong backbits[16*5];
ulong workbits[16*5];
Bitmap cursorwork =
{
	{0, 0, 16+8, 16},
	{0, 0, 16+8, 16},
	0,
	workbits,
	1,
	0,
};

void	Cursortocursor(Cursor*);
int	mousechanged(void*);

extern	void	screenload(Rectangle, uchar*, int, int, int);
extern	void	screenunload(Rectangle, uchar*, int, int, int);

enum{
	Qdir,
	Qcursor,


@@ 147,49 77,19 @@ extern	Bitmap	gscreen;
void
mousereset(void)
{
	ulong r;

	if(!conf.monitor)
		return;

	getcolor(0, &r, &r, &r);
	if(r == 0)
		flipping = 1;
	flipping = 0;	/* howard, why is this necessary to get a black arrow on carrera? */
	curs = arrow;
	Cursortocursor(&arrow);
}

void
cursorinit(void)
{
	cursorwork.ldepth = gscreen.ldepth;
	cursorwork.width = ((cursorwork.r.max.x << gscreen.ldepth) + 31) >> 5;

	cursor.l = cursorwork.width*BY2WD;

	if(flipping){
		cursor.setop = flipD[S|D];
		cursor.clrop = flipD[D&~S];
	} else {
		cursor.setop = S|D;
		cursor.clrop = D&~S;
	}
}

void
mouseinit(void)
{
	if(!conf.monitor)
		return;

	if(gscreen.ldepth > 3){
		print("mouse can't work ldepth > 3");
		cursor.disable = 1;
	}

	cursorinit();

	cursoron(1);
}



@@ 198,7 98,6 @@ mouseattach(char *spec)
{
	if(!conf.monitor)
		error(Egreg);
	cursorinit();
	return devattach('m', spec);
}



@@ 408,7 307,7 @@ Cursortocursor(Cursor *c)
	uchar *p;

	lock(&cursor);
	memmove(&cursor, c, sizeof(Cursor));
	memmove(&cursor.Cursor, c, sizeof(Cursor));
	for(i=0; i<16; i++){
		p = (uchar*)&setbits[i];
		*p = c->set[2*i];


@@ 417,115 316,10 @@ Cursortocursor(Cursor *c)
		*p = c->clr[2*i];
		*(p+1) = c->clr[2*i+1];
	}
	if(hwcurs)
		hwcursset(set.base, clr.base, cursor.offset.x, cursor.offset.y);
	unlock(&cursor);
}

void
cursorlock(Rectangle r)
{
	if(hwcurs)
		return;
	lock(&cursor);
	if(rectXrect(cursor.r, r)){
		cursoroff(0);
		cursor.frozen = 1;
	}
	cursor.disable++;
	setcursor(setbits, clrbits, cursor.offset.x, cursor.offset.y);
	unlock(&cursor);
}

void
cursorunlock(void)
{
	if(hwcurs)
		return;
	lock(&cursor);
	cursor.disable--;
	if(cursor.frozen)
		cursoron(0);
	cursor.frozen = 0;
	unlock(&cursor);
}

typedef struct
{
	Bitmap *dm;
	Point p;
	Bitmap *sm;
	Rectangle r;
	Fcode f;
} XXX;

void
cursoron(int dolock)
{
	int off;
	Rectangle r;
	uchar *a;
	XXX x;
	extern int graphicssubtile(uchar*, int, int, Rectangle, Rectangle, uchar**);

	if(cursor.disable)
		return;
	if(dolock)
		lock(&cursor);
	if(cursor.visible++ == 0){
		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);

			/* bit offset into backup area */
			off = ((1<<gscreen.ldepth)*cursor.r.min.x) & 7;

			/* clip the cursor rectangle */
			x.dm = &cursorwork;
			x.p = Pt(off, 0);
			x.sm = &gscreen;
			x.r = cursor.r;
			bitbltclip(&x);

			/* tile width */
			cursor.tl = graphicssubtile(0, cursor.l, gscreen.ldepth,
					gscreen.r, x.r, &a);
			if(cursor.tl > 0){
				/* get tile */
				screenunload(x.r, (uchar*)workbits, cursor.tl, cursor.l, 0);

				/* save for cursoroff */
				memmove(backbits, workbits, cursor.l*16);

				/* add mouse into work area */
				r = Rect(0, 0, Dx(x.r), Dy(x.r));
				bitblt(&cursorwork, x.p, &clr, r, cursor.clrop);
				bitblt(&cursorwork, x.p, &set, r, cursor.setop);

				/* put back tile */
				cursor.clipr = x.r;
				screenload(x.r, (uchar*)workbits, cursor.tl, cursor.l, 0);
			}
		}
	}
	if(dolock)
		unlock(&cursor);
}

void
cursoroff(int dolock)
{
	if(cursor.disable)
		return;
	if(dolock)
		lock(&cursor);
	if(--cursor.visible == 0 && !hwcurs && cursor.tl > 0)
		screenload(cursor.clipr, (uchar*)backbits, cursor.tl, cursor.l, 0);
	if(dolock)
		unlock(&cursor);
}

/*
 *  called by the clock routine to redraw the cursor


@@ 652,3 446,9 @@ mousechanged(void *m)
	USED(m);
	return mouse.lastcounter - mouse.counter;
}

Point
mousexy(void)
{
	return mouse.xy;
}

M port/portfns.h => port/portfns.h +1 -4
@@ 43,8 43,6 @@ void		copen(Chan*);
void		copypage(Page*, Page*);
int		cread(Chan*, uchar*, int, ulong);
void		cupdate(Chan*, uchar*, int, ulong);
void		cursoroff(int);
void		cursoron(int);
void		cwrite(Chan*, uchar*, int, ulong);
int		decref(Ref*);
int		decrypt(void*, void*, int);


@@ 93,8 91,6 @@ void		gotolabel(Label*);
int		haswaitq(void*);
long		hostdomainwrite(char*, int);
long		hostownerwrite(char*, int);
void		hwcursmove(int, int);
void		hwcursset(ulong*, ulong*, int, int);
void		iallocinit(void);
long		ibrk(ulong, int);
void		ilock(Lock*);


@@ 232,6 228,7 @@ long		seconds(void);
ulong		segattach(Proc*, ulong, char *, ulong, ulong);
void		segpage(Segment*, Page*);
int		setcolor(ulong, ulong, ulong, ulong);
void		setcursor(ulong*, ulong*, int, int);
void		setkernur(Ureg*, Proc*);
int		setlabel(Label*);
void		setregisters(Ureg*, char*, char*, int);