henesyinit from p9fd787fda5 years agoHistory
267 lines · 3.9 KB · C
RawDownload
#include	"lib9.h"#include	"sys.h"#include	"error.h"#include	"libdraw/draw.h"#include	"libmemdraw/memdraw.h"#include	"screen.h"  Mouseinfo	mouse;Cursorinfo	cursor; static int	mousechanged(void*); enum{	Qdir,	Qcursor,	Qmouse}; Dirtab mousedir[]={	"cursor",	{Qcursor},	0,			0666,	"mouse",	{Qmouse},	0,			0666,}; #define	NMOUSE	(sizeof(mousedir)/sizeof(Dirtab)) voidmousereset(void){} voidmouseinit(void){} Chan*mouseattach(void *spec){	return devattach('m', spec);} Chan*mouseclone(Chan *c, Chan *nc){	return devclone(c, nc);} intmousewalk(Chan *c, char *name){	return devwalk(c, name, mousedir, NMOUSE, devgen);} voidmousestat(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.lk);		if(mouse.open){			unlock(&mouse.lk);			error(Einuse);		}		mouse.open = 1;		unlock(&mouse.lk);		break;	}	c->mode = openmode(omode);	c->flag |= COPEN;	c->offset = 0;	return c;} voidmousecreate(Chan *c, char *name, int mode, ulong perm){	USED(c);	USED(name);	USED(mode);	USED(perm); 	error(Eperm);} voidmouseremove(Chan *c){	USED(c); 	error(Eperm);} voidmousewstat(Chan *c, char *s){	USED(c);	USED(s); 	error(Eperm);} voidmouseclose(Chan *c){	if(c->qid.path==CHDIR || !(c->flag&COPEN))		return; 	switch(c->qid.path) {	case Qmouse:		lock(&mouse.lk);		mouse.open = 0;		unlock(&mouse.lk);		cursorarrow();	}}  longmouseread(Chan *c, void *va, long n, ulong offset){	char buf[4*12+1];	uchar *p;	int i, nn;	ulong msec;/*	static int map[8] = {0, 4, 2, 6, 1, 5, 3, 7 };	*/ 	p = va;	switch(c->qid.path){	case CHDIR:		return devdirread(c, va, n, mousedir, NMOUSE, devgen); 	case Qcursor:		if(offset != 0)			return 0;		if(n < 2*4+2*2*16)			error(Eshort);		n = 2*4+2*2*16;		lock(&cursor.lk);		BPLONG(p+0, cursor.offset.x);		BPLONG(p+4, cursor.offset.y);		memmove(p+8, cursor.clr, 2*16);		memmove(p+40, cursor.set, 2*16);		unlock(&cursor.lk);		return n; 	case Qmouse:		while(mousechanged(0) == 0)			rendsleep(&mouse.r, mousechanged, 0); 		lock(&screen.lk);		if(screen.reshaped) {			screen.reshaped = 0;			sprint(buf, "t%11d %11d", 0, ticks());			if(n > 1+2*12)				n = 1+2*12;			memmove(va, buf, n);			unlock(&screen.lk);			return n;		}		unlock(&screen.lk); 		lock(&mouse.lk);		i = mouse.ri;		nn = (mouse.wi + Mousequeue - i) % Mousequeue;		if(nn < 1)			panic("empty mouse queue");		msec = ticks();		while(nn > 1) {			if(mouse.queue[i].msec + Mousewindow > msec)				break;			i = (i+1)%Mousequeue;			nn--;		}		sprint(buf, "m%11d %11d %11d %11d",			mouse.queue[i].xy.x,			mouse.queue[i].xy.y,			mouse.queue[i].buttons,			mouse.queue[i].msec);		mouse.ri = (i+1)%Mousequeue;		unlock(&mouse.lk);		if(n > 1+4*12)			n = 1+4*12;		memmove(va, buf, n);		return n;	}	return 0;} Block*mousebread(Chan *c, long n, ulong offset){	return devbread(c, n, offset);} longmousewrite(Chan *c, void *va, long n, ulong offset){	char *p;	Point pt;	char buf[64]; 	USED(offset); 	p = va;	switch(c->qid.path){	case CHDIR:		error(Eisdir); 	case Qcursor:		if(n < 2*4+2*2*16){			cursorarrow();		}else{			n = 2*4+2*2*16;			lock(&cursor.lk);			cursor.offset.x = BGLONG(p+0);			cursor.offset.y = BGLONG(p+4);			memmove(cursor.clr, p+8, 2*16);			memmove(cursor.set, p+40, 2*16);			unlock(&cursor.lk);			setcursor();		}		return n; 	case Qmouse:		if(n > sizeof buf-1)			n = sizeof buf -1;		memmove(buf, va, n);		buf[n] = 0;		p = 0;		pt.x = strtoul(buf+1, &p, 0);		if(p == 0)			error(Eshort);		pt.y = strtoul(p, 0, 0);		if(ptinrect(pt, gscreen->r))			mouseset(pt);		return n;	} 	error(Egreg);	return -1;} longmousebwrite(Chan *c, Block *bp, ulong offset){	return devbwrite(c, bp, offset);} intmousechanged(void *a){	USED(a); 	return mouse.ri != mouse.wi || screen.reshaped;}