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

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


## diffname port/devmouse.c 1993/1006
## diff -e /dev/null /n/fornaxdump/1993/1006/sys/src/brazil/port/devmouse.c
0a
#include	"u.h"
#include	"../port/lib.h"
#include	<libg.h>
#include	<gnot.h>
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"

#include	"devtab.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
{
	/*
	 * 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;
	Ref;
	QLock;
	int	open;
};

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

Mouseinfo	mouse;
Cursorinfo	cursor;
int		mouseshifted;
int		mousetype;
int		hwcurs;

Cursor	arrow =
{
	{-1, -1},
	{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,
	}
};

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

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

ulong cursorbackbits[16*4];
GBitmap cursorback =
{
	cursorbackbits,
	0,
	1,
	0,
	{0, 0, 16, 16},
	{0, 0, 16, 16}
};

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

enum{
	Qdir,
	Qmouse,
	Qmousectl,
};

Dirtab mousedir[]={
	"mouse",	{Qmouse},	0,			0666,
	"mousectl",	{Qmousectl},	0,			0220,
};

#define	NMOUSE	(sizeof(mousedir)/sizeof(Dirtab))

extern	GBitmap	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? */
	Cursortocursor(&arrow);
}

void
mouseinit(void)
{
	if(!conf.monitor)
		return;
	if(gscreen.ldepth > 3)
		cursorback.ldepth = 0;
	else{
		cursorback.ldepth = gscreen.ldepth;
		cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5;
	}
	cursoron(1);
}

Chan*
mouseattach(char *spec)
{
	if(!conf.monitor)
		error(Egreg);
	return devattach('m', spec);
}

Chan*
mouseclone(Chan *c, Chan *nc)
{
	nc = devclone(c, nc);
	if(c->qid.path != CHDIR)
		incref(&mouse);
	return nc;
}

int
mousewalk(Chan *c, char *name)
{
	return devwalk(c, name, mousedir, NMOUSE, devgen);
}

void
mousestat(Chan *c, char *db)
{
	devstat(c, db, mousedir, NMOUSE, devgen);
}

Chan*
mouseopen(Chan *c, int omode)
{
	switch(c->qid.path){
	case CHDIR:
		if(omode != OREAD)
			error(Eperm);
		break;
	case Qmouse:
		lock(&mouse);
		if(mouse.open){
			unlock(&mouse);
			error(Einuse);
		}
		mouse.open = 1;
		mouse.ref++;
		unlock(&mouse);
		break;
	default:
		incref(&mouse);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

void
mousecreate(Chan *c, char *name, int omode, ulong perm)
{
	if(!conf.monitor)
		error(Egreg);
	USED(c, name, omode, perm);
	error(Eperm);
}

void
mouseremove(Chan *c)
{
	USED(c);
	error(Eperm);
}

void
mousewstat(Chan *c, char *db)
{
	USED(c, db);
	error(Eperm);
}

void
mouseclose(Chan *c)
{
	if(c->qid.path!=CHDIR && (c->flag&COPEN)){
		lock(&mouse);
		if(c->qid.path == Qmouse)
			mouse.open = 0;
		unlock(&mouse);
	}
}

long
mouseread(Chan *c, void *va, long n, ulong offset)
{
	uchar *p;

	USED(offset);
	if(c->qid.path & CHDIR)
		return devdirread(c, va, n, mousedir, NMOUSE, devgen);

	if(c->qid.path == Qmouse){
		/*
		 * mouse:
		 *	'm'		1
		 *	buttons		1
		 * 	point		8
		 * 	msec		4
		 */
		if(n < 14)
			error(Eshort);
		while(mousechanged(0) == 0)
			sleep(&mouse.r, mousechanged, 0);
		lock(&cursor);
		p = va;
		p[0] = 'm';
		p[1] = mouse.buttons;
		BPLONG(p+2, mouse.xy.x);
		BPLONG(p+6, mouse.xy.y);
		BPLONG(p+10, TK2MS(MACHP(0)->ticks));
		mouse.lastcounter = mouse.counter;
		unlock(&cursor);
		return 14;
	}
	return 0;
}

long
mousewrite(Chan *c, void *va, long n, ulong offset)
{
	uchar *p;
	Point pt;
	char buf[64];

	USED(offset);

	switch(c->qid.path){
	case CHDIR:
		error(Eisdir);

	case Qmousectl:
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, va, n);
		buf[n] = 0;
		mousectl(buf);
		return n;

	case Qmouse:
		if(n != 9)
			error(Eshort);
		qlock(&mouse);
		p = va;
		pt.x = BGLONG(p+1);
		pt.y = BGLONG(p+5);
		if(ptinrect(pt, gscreen.r)){
			mouse.xy = pt;
			mouse.redraw = 1;
			mouse.track = 1;
			mouseclock();
		}
		qunlock(&mouse);
		return n;
	}

	error(Egreg);
	return -1;
}

void
Cursortocursor(Cursor *c)
{
	int i;
	uchar *p;

	lock(&cursor);
	memmove(&cursor, c, sizeof(Cursor));
	for(i=0; i<16; i++){
		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];
	}
	if(hwcurs)
		hwcursset(set.base, clr.base, cursor.offset.x, cursor.offset.y);
	unlock(&cursor);
}

void
cursoron(int dolock)
{
	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);
			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);
		}
	}
	if(dolock)
		unlock(&cursor);
}

void
cursoroff(int dolock)
{
	if(cursor.disable)
		return;
	if(dolock)
		lock(&cursor);
	if(--cursor.visible == 0) {
		if(!hwcurs) {
			gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
			mbbrect(cursor.r);
			mousescreenupdate();
		}
	}
	if(dolock)
		unlock(&cursor);
}

/*
 *  called by the clock routine to redraw the cursor
 */
void
mouseclock(void)
{
	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);
	}
}

/*
 *  called at interrupt level to update the structure and
 *  awaken any waiting procs.
 */
void
mousetrack(int b, int dx, int dy)
{
	int x, y;

	x = mouse.xy.x + 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 + dy;
	if(y < gscreen.r.min.y)
		y = gscreen.r.min.y;
	if(y >= gscreen.r.max.y)
		y = gscreen.r.max.y;
	mouse.counter++;
	mouse.xy = Pt(x, y);
	mouse.buttons = b;
	mouse.redraw = 1;
	wakeup(&mouse.r);
}

/*
 *  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 & right 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 int middle;
	static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 5 };
	short x;
	int dx, dy, newbuttons;

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

/*
 *  Logitech 5 byte packed binary mouse format, 8 bit bytes
 *
 *  shift & right button is the same as middle button (for 2 button mice)
 */
int
mouseputc(IOQ *q, int c)
{
	static short msg[5];
	static int nb;
	static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 5, 3, 7};
	int dx, dy, newbuttons;

	USED(q);
	if((c&0xF0) == 0x80)
		nb=0;
	msg[nb] = c;
	if(c & 0x80)
		msg[nb] |= ~0xFF;	/* sign extend */
	if(++nb == 5){
		newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
		dx = msg[1]+msg[3];
		dy = -(msg[2]+msg[4]);
		mousetrack(newbuttons, dx, dy);
		nb = 0;
	}
	return 0;
}

int
mousechanged(void *m)
{
	USED(m);
	return mouse.lastcounter - mouse.counter;
}
.
## diffname port/devmouse.c 1993/1008
## diff -e /n/fornaxdump/1993/1006/sys/src/brazil/port/devmouse.c /n/fornaxdump/1993/1008/sys/src/brazil/port/devmouse.c
311,313d
309a
		pt.y = strtoul(p, 0, 0);
.
308c
		if(n > sizeof buf-1)
			n = sizeof buf -1;
		memmove(buf, va, n);
		buf[n] = 0;
		p = 0;
		pt.x = strtoul(buf, &p, 0);
		if(p == 0)
.
289c
	char *p;
.
281c
		if(n > 4*12)
			n = 4*12;
		memmove(va, buf, n);
		return n;
.
273,278c
		sprint(buf, "%11d %11d %11d %11d",
			mouse.xy.x, mouse.xy.y, mouse.buttons,
			TK2MS(MACHP(0)->ticks));
.
261,269d
254c
	char buf[4*12+1];
.
## diffname port/devmouse.c 1993/1009
## diff -e /n/fornaxdump/1993/1008/sys/src/brazil/port/devmouse.c /n/fornaxdump/1993/1009/sys/src/brazil/port/devmouse.c
288a

	case Qcursor:
		cursoroff(1);
		if(n < 2*4+2*2*16){
			curs = arrow;
			Cursortocursor(&arrow);
		}else{
			n = 2*4+2*2*16;
			curs.offset.x = BGLONG(p+0);
			curs.offset.y = BGLONG(p+4);
			memmove(curs.clr, p+8, 2*16);
			memmove(curs.set, p+40, 2*16);
			Cursortocursor(&curs);
		}
		cursoron(1);
		return n;
.
284,285c
	p = va;
.
260c
	case Qcursor:
		if(offset != 0)
			return 0;
		if(n < 2*4+2*2*16)
			error(Eshort);
		n = 2*4+2*2*16;
		lock(&cursor);
		BPLONG(p+0, curs.offset.x);
		BPLONG(p+4, curs.offset.y);
		memmove(p+8, curs.clr, 2*16);
		memmove(p+40, curs.set, 2*16);
		unlock(&cursor);
		return n;

	case Qmouse:
.
256,257c
	p = va;
	switch(c->qid.path){
	case CHDIR:
.
254a
	uchar *p;
.
246a
		if(--mouse.ref == 0){
			cursoroff(1);
			curs = arrow;
			Cursortocursor(&arrow);
			cursoron(1);
		}
.
143a
	curs = arrow;
.
123a
	"cursor",	{Qcursor},	0,			0666,
.
118a
	Qcursor,
.
64a
Cursor	curs;
.
## diffname port/devmouse.c 1993/1026
## diff -e /n/fornaxdump/1993/1009/sys/src/brazil/port/devmouse.c /n/fornaxdump/1993/1026/sys/src/brazil/port/devmouse.c
381a
	unlock(&cursor);
}

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

void
cursorunlock(void)
{
	if(hwcurs)
		return;
	lock(&cursor);
	cursor.disable--;
	if(cursor.frozen)
		cursoron(0);
	cursor.frozen = 0;
.
56a
	int	frozen;	/* from being used */
.
## diffname port/devmouse.c 1993/1108
## diff -e /n/fornaxdump/1993/1026/sys/src/brazil/port/devmouse.c /n/fornaxdump/1993/1108/sys/src/brazil/port/devmouse.c
328a
		qlock(&mouse);
		mouse.redraw = 1;
		mouseclock();
		qunlock(&mouse);
.
## diffname port/devmouse.c 1993/1201
## diff -e /n/fornaxdump/1993/1108/sys/src/brazil/port/devmouse.c /n/fornaxdump/1993/1201/sys/src/brazil/port/devmouse.c
567d
560c
mouseputc(int c)
.
528d
519c
m3mouseputc(int c)
.
## diffname port/devmouse.c 1994/0210
## diff -e /n/fornaxdump/1993/1201/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0210/sys/src/brazil/port/devmouse.c
10a
#include	"screen.h"
.
## diffname port/devmouse.c 1994/0216
## diff -e /n/fornaxdump/1994/0210/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0216/sys/src/brazil/port/devmouse.c
293c
			mouse.xy.x, mouse.xy.y,
			mouseswap ? map[mouse.buttons&7] : mouse.buttons,
.
267a
	static int map[8] = {0, 4, 2, 6, 1, 5, 3, 7 };
.
262a

.
65a
int		mouseswap;
.
## diffname port/devmouse.c 1994/0325
## diff -e /n/fornaxdump/1994/0216/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0325/sys/src/brazil/port/devmouse.c
315a
	USED(offset);
.
## diffname port/devmouse.c 1994/0412
## diff -e /n/fornaxdump/1994/0325/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0412/sys/src/brazil/port/devmouse.c
483d
457,461c
		if(!hwcurs)
			screenload(cursor.r, (uchar*)cursorbackbits,
				(16>>3) << gscreen.ldepth, cursorback.width*BY2WD, 0);
.
442c
			screenload(cursor.r, (uchar*)cursorworkbits,
				(16>>3) << gscreen.ldepth, cursorwork.width*BY2WD, 0);
.
440c
			gbitblt(&cursorwork, cursorwork.r.min,
.
437,438c
			screenunload(cursor.r, (uchar*)cursorworkbits,
				(16>>3) << gscreen.ldepth, cursorwork.width*BY2WD, 0);
			memmove(cursorbackbits, cursorworkbits, 16*cursorback.width*BY2WD);
			gbitblt(&cursorwork, cursorwork.r.min,
.
163a
		cursorwork.ldepth = gscreen.ldepth;
		cursorwork.width = ((16 << gscreen.ldepth) + 31) >> 5;
.
161c
		cursorwork.ldepth = 0;
	}else{
.
159c
	if(gscreen.ldepth > 3){
.
120a
extern	void	screenload(Rectangle, uchar*, int, int, int);
extern	void	screenunload(Rectangle, uchar*, int, int, int);

.
117a
ulong cursorworkbits[16*4];
GBitmap cursorwork =
{
	cursorworkbits,
	0,
	1,
	0,
	{0, 0, 16, 16},
	{0, 0, 16, 16}
};

.
## diffname port/devmouse.c 1994/0413
## diff -e /n/fornaxdump/1994/0412/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0413/sys/src/brazil/port/devmouse.c
476,480c
	if(--cursor.visible == 0 && !hwcurs && cursor.tl > 0)
		screenload(cursor.clipr, (uchar*)backbits, cursor.tl, cursor.l, 0);
.
454,462c

			/* 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);
			}
.
442a
	int off;
	Rectangle r;
	uchar *a;
	XXX x;
	extern int graphicssubtile(uchar*, int, int, Rectangle, Rectangle, uchar**);

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

.
189a
	cursorinit();
.
181a

	cursorinit();

.
174,180c
		print("mouse can't work ldepth > 3");
		cursor.disable = 1;
.
172a

.
168a
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
.
150c
extern	Bitmap	gscreen;
.
125,126d
122a
	workbits,
.
121c
	{0, 0, 16+8, 16},
	{0, 0, 16+8, 16},
.
118,119c
ulong backbits[16*5];
ulong workbits[16*5];
Bitmap cursorwork =
.
114,115d
111a
	clrbits,
.
104,110c
	{0, 0, 16, 16},
.
99,102d
97c
Bitmap	clr =
.
92,93d
89a
	setbits,
.
88c
	{0, 0, 16, 16},
	{0, 0, 16, 16},
.
86c
Bitmap	set =
.
59a

	int	l;
	int	tl;
	int	setop;
	int	clrop;
	Rectangle clipr;
.
4d
## diffname port/devmouse.c 1994/0414
## diff -e /n/fornaxdump/1994/0413/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0414/sys/src/brazil/port/devmouse.c
653a
}

Point
mousexy(void)
{
	return mouse.xy;
.
439,529d
425,437d
420,421c
	setcursor(setbits, clrbits, cursor.offset.x, cursor.offset.y);
.
411c
	memmove(&cursor.Cursor, c, sizeof(Cursor));
.
201d
186,192d
164,180d
155,158d
150,151d
127,129d
112,123d
102,110d
91,100d
72,73c
Cursor		curs;
.
51,66d
31d
12,29d
## diffname port/devmouse.c 1994/0520
## diff -e /n/fornaxdump/1994/0414/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0520/sys/src/brazil/port/devmouse.c
311,319c
	setcursor(c);
.
306,308d
54,56d
## diffname port/devmouse.c 1994/0521
## diff -e /n/fornaxdump/1994/0520/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0521/sys/src/brazil/port/devmouse.c
47,51c
	{ 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, 
	},
.
39,45c
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, 
.
## diffname port/devmouse.c 1994/0624
## diff -e /n/fornaxdump/1994/0521/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0624/sys/src/brazil/port/devmouse.c
324c
		mouse.redraw = cursoron(0);
.
## diffname port/devmouse.c 1994/0730
## diff -e /n/fornaxdump/1994/0624/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0730/sys/src/brazil/port/devmouse.c
412a
	USED(q);
.
406c
mouseputc(void *q, int c)
.
374a
	USED(q);

.
366c
m3mouseputc(void *q, int c)
.
## diffname port/devmouse.c 1994/0913
## diff -e /n/fornaxdump/1994/0730/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/0913/sys/src/brazil/port/devmouse.c
352a
	graphicsactive(1);
.
326a
	graphicsactive(0);
.
## diffname port/devmouse.c 1994/1013
## diff -e /n/fornaxdump/1994/0913/sys/src/brazil/port/devmouse.c /n/fornaxdump/1994/1013/sys/src/brazil/port/devmouse.c
280c
		pt.x = strtoul(buf+1, &p, 0);
.
225,226c
		if(n > 1+4*12)
			n = 1+4*12;
.
219c
		sprint(buf, "m%11d %11d %11d %11d",
.
## diffname port/devmouse.c 1995/0108
## diff -e /n/fornaxdump/1994/1013/sys/src/brazil/port/devmouse.c /n/fornaxdump/1995/0108/sys/src/brazil/port/devmouse.c
296a
}

long
mousebwrite(Chan *c, Block *bp, ulong offset)
{
	return devbwrite(c, bp, offset);
.
232a
Block*
mousebread(Chan *c, long n, ulong offset)
{
	return devbread(c, n, offset);
}

.
## diffname port/devmouse.c 1995/0804
## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/port/devmouse.c /n/fornaxdump/1995/0804/sys/src/brazil/port/devmouse.c
448d
446c
mousechanged(void*)
.
429d
422c
mouseputc(void*, int c)
.
389,390d
380c
m3mouseputc(void*, int c)
.
246d
240c
mousewrite(Chan *c, void *va, long n, ulong)
.
167d
165c
mousewstat(Chan*, char*)
.
160d
158c
mouseremove(Chan*)
.
153d
149c
mousecreate(Chan*, char*, int, ulong)
.
## diffname port/devmouse.c 1995/0812
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/devmouse.c /n/fornaxdump/1995/0812/sys/src/brazil/port/devmouse.c
215c

		while(!canlock(&cursor))
			tsleep(&up->sleep, return0, 0, TK2MS(1));

.
## diffname port/devmouse.c 1995/1216
## diff -e /n/fornaxdump/1995/0812/sys/src/brazil/port/devmouse.c /n/fornaxdump/1995/1216/sys/src/brazil/port/devmouse.c
450a
}

void
mouseaccelerate(char *x)
{
	if(x == 0)
		x = "1";
	mouse.acceleration = atoi(x);
	if(mouse.acceleration < 3)
		mouse.maxacc = 2;
	else
		mouse.maxacc = mouse.acceleration;
.
349a
	if(mouse.acceleration){
		dx = scale(dx);
		dy = scale(dy);
	}
.
340a
static int
scale(int x)
{
	int sign = 1;

	if(x < 0){
		sign = -1;
		x = -x;
	}
	switch(x){
	case 0:
	case 1:
	case 2:
	case 3:
		break;
	case 4:
		x = 6 + (mouse.acceleration>>2);
		break;
	case 5:
		x = 9 + (mouse.acceleration>>1);
		break;
	default:
		x *= mouse.maxacc;
		break;
	}
	return sign*x;
}

.
275c
		if(buf[n - 1] == '\n')
			buf[n-1] = 0;
		else
			buf[n] = 0;
.
29a
	int	acceleration;
	int	maxacc;
.
## diffname port/devmouse.c 1996/0223
## diff -e /n/fornaxdump/1995/1216/sys/src/brazil/port/devmouse.c /n/fornaxdump/1996/0223/sys/src/brazil/port/devmouse.c
9d
## diffname port/devmouse.c 1997/0201
## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/port/devmouse.c /n/emeliedump/1997/0201/sys/src/brazil/port/devmouse.c
3c
#include	<libgb.h>
.
## diffname port/devmouse.c 1997/0202
## diff -e /n/emeliedump/1997/0201/sys/src/brazil/port/devmouse.c /n/emeliedump/1997/0202/sys/src/brazil/port/devmouse.c
3c
#include	<libg.h>
.
## diffname port/devmouse.c 1997/0327
## diff -e /n/emeliedump/1997/0202/sys/src/brazil/port/devmouse.c /n/emeliedump/1997/0327/sys/src/brazil/port/devmouse.c
327c
static void
.
308,312c
Dev mousedevtab = {
	mousereset,
	mouseinit,
	mouseattach,
	mouseclone,
	mousewalk,
	mousestat,
	mouseopen,
	mousecreate,
	mouseclose,
	mouseread,
	devbread,
	mousewrite,
	devbwrite,
	devremove,
	devwstat,
};
.
234,240c
static long
.
197c
		return devdirread(c, va, n, mousedir, nelem(mousedir), devgen);
.
187c
static long
.
157,169c
static void
.
149c
static void
.
122c
static Chan*
.
119c
	devstat(c, db, mousedir, nelem(mousedir), devgen);
.
116c
static void
.
113c
	return devwalk(c, name, mousedir, nelem(mousedir), devgen);
.
110c
static int
.
101c
static Chan*
.
93c
static Chan*
.
84c
static void
.
81a
	addclock0link(mouseclock);
.
74c
static void
.
70,71d
55a
static void mouseclock(void);
.
8a
#include	<libg.h>
.
3d
## diffname port/devmouse.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devmouse.c /n/emeliedump/1997/0408/sys/src/brazil/port/devmouse.c
290a
	'm',
	"mouse",

.
## diffname port/devmouse.c 1997/1101
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devmouse.c /n/emeliedump/1997/1101/sys/src/brazil/port/devmouse.c
398c
	drawactive(1);
.
339c
	drawactive(0);
.
71c
extern	Memimage	gscreen;
.
36d
20c
	int	track;		/* dx & dy updated */
.
15,17d
8c
#define	Image	IMAGE
#define	mouse	moose
#include	<draw.h>
#undef	mouse
#include	<memdraw.h>
.
## diffname port/devmouse.c 1997/1112
## diff -e /n/emeliedump/1997/1101/sys/src/brazil/port/devmouse.c /n/emeliedump/1997/1112/sys/src/brazil/port/devmouse.c
425c
		/*
		 * an extra byte comes for middle button motion.
		 * only two possible values for the extra byte.
		 */
		if(c == 0x00 || c == 0x20){
.
421,423d
## diffname port/devmouse.c 1998/0209
## diff -e /n/emeliedump/1997/1112/sys/src/brazil/port/devmouse.c /n/emeliedump/1998/0209/sys/src/brazil/port/devmouse.c
40,53d
## diffname port/devmouse.c 1998/0319
## diff -e /n/emeliedump/1998/0209/sys/src/brazil/port/devmouse.c /n/emeliedump/1998/0319/sys/src/brazil/port/devmouse.c
209c
mousewrite(Chan *c, void *va, long n, vlong)
.
166a
	ulong offset = off;
.
162c
mouseread(Chan *c, void *va, long n, vlong off)
.
## diffname port/devmouse.c 1998/0417
## diff -e /n/emeliedump/1998/0319/sys/src/brazil/port/devmouse.c /n/emeliedump/1998/0417/sys/src/brazil/port/devmouse.c
249c
		nf = parsefields(buf, field, 3, " ");
		if(strcmp(field[0], "swap") == 0){
			if(mouseswap)
				setbuttonmap("123");
			else
				setbuttonmap("321");
			mouseswap ^= 1;
		}
		else if(strcmp(field[0], "buttonmap") == 0){
			if(nf == 1)
				setbuttonmap("123");
			else
				setbuttonmap(field[1]);
		}
		else
			mousectl(field, nf);
.
214c
	char buf[64], *field[3];
	int nf;
.
208a
static void
setbuttonmap(char* map)
{
	int i, x, one, two, three;

	one = two = three = 0;
	for(i = 0; i < 3; i++){
		if(map[i] == 0)
			error(Ebadarg);
		if(map[i] == '1'){
			if(one)
				error(Ebadarg);
			one = 1<<i;
		}
		else if(map[i] == '2'){
			if(two)
				error(Ebadarg);
			two = 1<<i;
		}
		else if(map[i] == '3'){
			if(three)
				error(Ebadarg);
			three = 1<<i;
		}
		else
			error(Ebadarg);
	}
	if(map[i])
		error(Ebadarg);

	memset(buttonmap, 0, 8);
	for(i = 0; i < 8; i++){
		x = 0;
		if(i & 1)
			x |= one;
		if(i & 2)
			x |= two;
		if(i & 4)
			x |= three;
		buttonmap[x] = i;
	}
}

.
197c
			buttonmap[mouse.buttons&7],
.
56a
static uchar buttonmap[8] = {
	0, 1, 2, 3, 4, 5, 6, 7,
};
static int mouseswap;

.
51c
static Dirtab mousedir[]={
.
37d
## diffname port/devmouse.c 1998/0825
## diff -e /n/emeliedump/1998/0417/sys/src/brazil/port/devmouse.c /n/emeliedump/1998/0825/sys/src/brazil/port/devmouse.c
199c
		sprint(buf, "m%11d %11d %11d %11lud",
.
## diffname port/devmouse.c 1999/0119
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/port/devmouse.c /n/emeliedump/1999/0119/sys/src/brazil/port/devmouse.c
22c
	Point	xy;			/* mouse.xy */
	int	buttons;		/* mouse.buttons */
.
12a
#include	<cursor.h>
.
11d
9d
## diffname port/devmouse.c 1999/0225
## diff -e /n/emeliedump/1999/0119/sys/src/brazil/port/devmouse.c /n/emeliedump/1999/0225/sys/src/brazil/port/devmouse.c
540,542c
	mouse.acceleration = x;
.
538c
mouseaccelerate(int x)
.
## diffname port/devmouse.c 1999/0320
## diff -e /n/emeliedump/1999/0225/sys/src/brazil/port/devmouse.c /n/emeliedump/1999/0320/sys/src/brazil/port/devmouse.c
503c
mouseputc(Queue*, int c)
.
462c
m3mouseputc(Queue*, int c)
.
## diffname port/devmouse.c 1999/1005
## diff -e /n/emeliedump/1999/0320/sys/src/brazil/port/devmouse.c /n/emeliedump/1999/1005/sys/src/brazil/port/devmouse.c
439,442c
	if(y < gscreen->r.min.y)
		y = gscreen->r.min.y;
	if(y >= gscreen->r.max.y)
		y = gscreen->r.max.y;
.
434,437c
	if(x < gscreen->r.min.x)
		x = gscreen->r.min.x;
	if(x >= gscreen->r.max.x)
		x = gscreen->r.max.x;
.
428a
	if(gscreen==nil)
		return;

.
326c
		if(ptinrect(pt, gscreen->r)){
.
61c
extern	Memimage*	gscreen;
.
## diffname port/devmouse.c 1999/1012
## diff -e /n/emeliedump/1999/1005/sys/src/brazil/port/devmouse.c /n/emeliedump/1999/1012/sys/src/brazil/port/devmouse.c
314a
	case Qmousein:
		if(n > sizeof buf-1)
			n = sizeof buf -1;
		memmove(buf, va, n);
		buf[n] = 0;
		p = 0;
		pt.x = strtol(buf+1, &p, 0);
		if(p == 0)
			error(Eshort);
		pt.y = strtol(p, &p, 0);
		if(p == 0)
			error(Eshort);
		b = strtol(p, &p, 0);
		mousetrack(b, pt.x, pt.y);
		return n;
		
.
262c
	int nf, b;
.
153a
		else if(c->qid.path == Qmousein){
			mouse.inopen = 0;
			unlock(&mouse);
			return;
		}
.
129a
	case Qmousein:
		lock(&mouse);
		if(mouse.inopen){
			unlock(&mouse);
			error(Einuse);
		}
		mouse.inopen = 1;
		unlock(&mouse);
		break;
.
52a
	"mousein",	{Qmousein},	0,			0220,
.
46a
	Qmousein,
.
29a
	int	inopen;
.
## diffname port/devmouse.c 2000/0308
## diff -e /n/emeliedump/1999/1012/sys/src/brazil/port/devmouse.c /n/emeliedump/2000/0308/sys/src/9/port/devmouse.c
314c
		nf = getfields(buf, field, 3, 1, " ");
.
## diffname port/devmouse.c 2000/0314
## diff -e /n/emeliedump/2000/0308/sys/src/9/port/devmouse.c /n/emeliedump/2000/0314/sys/src/9/port/devmouse.c
564c
	return mouse.lastcounter != mouse.counter;
.
482a
	mouse.counter++;
	mouse.msec = TK2MS(MACHP(0)->ticks);

	/*
	 * if the queue fills, we discard the entire queue and don't
	 * queue any more events until a reader polls the mouse.
	 */
	if(!mouse.qfull && lastb != b) {	/* add to ring */
		mouse.queue[mouse.wi] = mouse.Mousestate;
		if(++mouse.wi == nelem(mouse.queue))
			mouse.wi = 0;
		if(mouse.wi == mouse.ri)
			mouse.qfull = 1;
	}
.
479c

	lastb = mouse.buttons;
.
460c
	int x, y, lastb;
.
217,221c
			m.xy.x, m.xy.y,
			buttonmap[m.buttons&7],
			m.msec);
		mouse.lastcounter = m.counter;
.
215a
		/*
		 * No lock of the indicies is necessary here, because ri is only
		 * updated by us, and there is only one mouse reader
		 * at a time.  I suppose that more than one process
		 * could try to read the fd at one time, but such behavior
		 * is degenerate and already violates the calling
		 * conventions for sleep above.
		 */
		if(mouse.ri != mouse.wi) {
			m = mouse.queue[mouse.ri];
			if(++mouse.ri == nelem(mouse.queue))
				mouse.ri = 0;
		} else {
			while(!canlock(&cursor))
				tsleep(&up->sleep, return0, 0, TK2MS(1));
	
			m = mouse.Mousestate;
			unlock(&cursor);
		}

.
213,214c
		mouse.qfull = 0;
.
188a
	Mousestate m;
.
32a
	Mousestate 	queue[16];	/* circular buffer of click events */
	int	ri;	/* read index into queue */
	int	wi;	/* write index into queue */
	uchar	qfull;	/* queue is full */
.
24d
21,22d
17a
	Mousestate;
.
15a
struct Mousestate
{
	Point	xy;			/* mouse.xy */
	int	buttons;		/* mouse.buttons */
	ulong	counter;	/* increments every update */
	ulong	msec;	/* time of last event */
};

.
14a
typedef struct Mousestate	Mousestate;
.
## diffname port/devmouse.c 2000/0516
## diff -e /n/emeliedump/2000/0314/sys/src/9/port/devmouse.c /n/emeliedump/2000/0516/sys/src/9/port/devmouse.c
144a
		error("disabled");
.
## diffname port/devmouse.c 2000/0716
## diff -e /n/emeliedump/2000/0516/sys/src/9/port/devmouse.c /n/emeliedump/2000/0716/sys/src/9/port/devmouse.c
589c
	static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 3, 3, 7};
.
549c
	static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 3 };
.
145c
	/*	error("disabled");	*/
.
## diffname port/devmouse.c 2000/1012
## diff -e /n/emeliedump/2000/0716/sys/src/9/port/devmouse.c /n/emeliedump/2000/1012/sys/src/9/port/devmouse.c
250c
			b,
.
247a
		b = buttonmap[m.buttons&7];
		/* put buttons 4 and 5 back in */
		b |= m.buttons & (3<<3);
.
201a
	int b;
.
## diffname port/devmouse.c 2001/0527
## diff -e /n/emeliedump/2000/1012/sys/src/9/port/devmouse.c /n/emeliedump/2001/0527/sys/src/9/port/devmouse.c
605c
		mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
.
578c
		mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
.
566c
			mousetrack(0, 0, newbuttons, TK2MS(MACHP(0)->ticks));
.
520c
	mouse.msec = msec;
.
493c
mousetrack(int dx, int dy, int b, int msec)
.
446c
		mousetrack(mouse.dx, mouse.dy, mouse.buttons, TK2MS(MACHP(0)->ticks));
.
415d
380c
		msec = strtol(p, &p, 0);
		if(msec == 0)
			msec = TK2MS(MACHP(0)->ticks);
		mousetrack(pt.x, pt.y, b, msec);
.
317,318c
	switch((ulong)c->qid.path){
	case Qdir:
.
314c
	int nf, b, msec;
.
205,206c
	switch((ulong)c->qid.path){
	case Qdir:
.
174c
	if((c->qid.type&QTDIR)==0 && (c->flag&COPEN)){
.
129,130c
	switch((ulong)c->qid.path){
	case Qdir:
.
120,125d
117c
	return devstat(c, db, n, mousedir, nelem(mousedir), devgen);
.
115c
mousestat(Chan *c, uchar *db, int n)
.
111c
	return wq;
.
108,109c
	Walkqid *wq;

	wq = devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen);
	if(wq != nil && wq->clone != c && (wq->clone->qid.type&QTDIR)==0)
.
105,106c
static Walkqid*
mousewalk(Chan *c, Chan *nc, char **name, int nname)
.
63a
	".",	{Qdir, 0, QTDIR},	0,			DMDIR|0555,
.
## diffname port/devmouse.c 2001/1015
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/devmouse.c /n/emeliedump/2001/1015/sys/src/9/port/devmouse.c
509,512c
	if(y < gscreen->clipr.min.y)
		y = gscreen->clipr.min.y;
	if(y >= gscreen->clipr.max.y)
		y = gscreen->clipr.max.y;
.
504,507c
	if(x < gscreen->clipr.min.x)
		x = gscreen->clipr.min.x;
	if(x >= gscreen->clipr.max.x)
		x = gscreen->clipr.max.x;
.
## diffname port/devmouse.c 2001/1117
## diff -e /n/emeliedump/2001/1015/sys/src/9/port/devmouse.c /n/emeliedump/2001/1117/sys/src/9/port/devmouse.c
346c
		nf = tokenize(buf, field, 3);
.
## diffname port/devmouse.c 2001/1120
## diff -e /n/emeliedump/2001/1117/sys/src/9/port/devmouse.c /n/emeliedump/2001/1120/sys/src/9/port/devmouse.c
360,361c

		free(cb);
		poperror();
.
358c
				setbuttonmap(cb->f[1]);
			break;

		case CMwildcard:
			mousectl(cb);
			break;
.
353,355c
			break;

		case CMbuttonmap:
			if(cb->nf == 1)
.
339,347c
		cb = parsecmd(va, n);
		if(waserror()){
			free(cb);
			nexterror();
		}

		ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));

		switch(ct->index){
		case CMswap:
.
310,311c
	Cmdbuf *cb;
	Cmdtab *ct;
	char buf[64];
	int b, msec;
.
45a
enum
{
	CMbuttonmap,
	CMswap,
	CMwildcard,
};

static Cmdtab mousectlmsg[] =
{
	CMbuttonmap,	"buttonmap",	0,
	CMswap,		"swap",		1,
	CMwildcard,	"*",			0,
};

.
## diffname port/devmouse.c 2002/0109
## diff -e /n/emeliedump/2001/1120/sys/src/9/port/devmouse.c /n/emeliedump/2002/0109/sys/src/9/port/devmouse.c
437a
	devshutdown,
.
## diffname port/devmouse.c 2002/0502
## diff -e /n/emeliedump/2002/0109/sys/src/9/port/devmouse.c /n/emeliedump/2002/0502/sys/src/9/port/devmouse.c
156c
		if(!iseve())
			error(Eperm);
.
## diffname port/devmouse.c 2002/0928
## diff -e /n/emeliedump/2002/0502/sys/src/9/port/devmouse.c /n/emeliedump/2002/0928/sys/src/9/port/devmouse.c
100c
	/* redraw cursor about 30 times per second */
	addclock0link(mouseclock, 33);
.
## diffname port/devmouse.c 2002/1109
## diff -e /n/emeliedump/2002/0928/sys/src/9/port/devmouse.c /n/emeliedump/2002/1109/sys/src/9/port/devmouse.c
127c
	if(wq != nil && wq->clone != c && wq->clone != nil && (wq->clone->qid.type&QTDIR)==0)
.
## diffname port/devmouse.c 2003/0326
## diff -e /n/emeliedump/2002/1109/sys/src/9/port/devmouse.c /n/emeliedump/2003/0326/sys/src/9/port/devmouse.c
109a
	curs = arrow;
	Cursortocursor(&arrow);
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].