311 lines · 6.5 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <cursor.h>#include <event.h>#include <bio.h>#include "proof.h" static	int	checkmouse(void);static	int	buttondown(void);static	char	*getmousestr(void);static	char	*getkbdstr(int); extern	Cursor	blot;extern	char	*track; Mouse	mouse; voidmapscreen(void){	if(initdraw(0, 0, "proof") < 0){		fprint(2, "proof: initdraw failed: %r\n");		exits("initdraw");	}	einit(Ekeyboard|Emouse);} voidclearscreen(void){	draw(screen, screen->r, display->black, nil, ZP);} voidscreenprint(char *fmt, ...){	char buf[100];	Point p;	va_list args; 	va_start(args, fmt);	vseprint(buf, &buf[sizeof buf], fmt, args);	va_end(args);	p = Pt(screen->clipr.min.x+40, screen->clipr.max.y-40);	string(screen, p, display->black, ZP, font, buf);} #define	Viewkey	0xb2 char *getcmdstr(void){	Event ev;	int e;	static ulong timekey = 0;	ulong tracktm = 0;	Dir *dir; 	if(track){		if(timekey == 0)			timekey = etimer(0, 5000);		dir = dirstat(track);		if(dir != nil){			tracktm = dir->mtime;			free(dir);		}	}	for (;;) {		e = event(&ev);		if(resized){			resized = 0;			return "p";		}		if ((e & Emouse) && ev.mouse.buttons) {			mouse = ev.mouse;			return getmousestr();		} else if (e & Ekeyboard)			return getkbdstr(ev.kbdc);	/* sadly, no way to unget */		else if (e & timekey) {			if((dir = dirstat(track)) != nil){				if(tracktm < dir->mtime){					free(dir);					return "q";				}				free(dir);			}		}	}} static char *getkbdstr(int c0){	static char buf[100];	char *p;	int c; 	if (c0 == '\n')		return "";	buf[0] = c0;	buf[1] = 0;	screenprint("%s", buf);	for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) {		if (c == '\b' && p > buf) {			*--p = ' ';		} else {			*p++ = c;			*p = 0;		}		screenprint("%s", buf);	}	*p = 0;	return buf;}  #define button3(b)	((b) & 4)#define button2(b)	((b) & 2)#define button1(b)	((b) & 1)#define button23(b)	((b) & 6)#define button123(b)	((b) & 7) #define	butcvt(b)	(1 << ((b) - 1)) static int buttondown(void)	/* report state of buttons, if any */{	if (!ecanmouse())	/* no event pending */		return 0;	mouse = emouse();	/* something, but it could be motion */	return mouse.buttons & 7;} int waitdown(void)	/* wait until some button is down */{	while (!(mouse.buttons & 7))		mouse = emouse();	return mouse.buttons & 7;} int waitup(void){	while (mouse.buttons & 7)		mouse = emouse();	return mouse.buttons & 7;} char *m3[]	= { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 };char *m2[]	= { 0 }; enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit }; Menu	mbut3	= { m3, 0, 0 };Menu	mbut2	= { m2, 0, 0 }; int	last_hit;int	last_but; char *pan(void){	Point dd, xy, lastxy, min, max; 	esetcursor(&blot);	waitdown();	xy = mouse.xy;	do{		lastxy = mouse.xy;		mouse = emouse();		dd = subpt(mouse.xy, lastxy);		min = addpt(screen->clipr.min, dd);		max = addpt(screen->clipr.max, dd);		draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)),			screen, nil, screen->r.min);		if(mouse.xy.x < lastxy.x)	/* moved left, clear right */			draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y),				display->white, nil, ZP);		else	/* moved right, clear left*/			draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y),				display->white, nil, ZP);		if(mouse.xy.y < lastxy.y)	/* moved up, clear down */			draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y),				display->white, nil, ZP);		else		/* moved down, clear up */			draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y),				display->white, nil, ZP);		flushimage(display, 1);	}while(mouse.buttons); 	xyoffset = addpt(xyoffset, subpt(mouse.xy, xy)); 	esetcursor(0);	return "p";} static char *getmousestr(void){	static char buf[64]; 	checkmouse();	if (last_but == 1)		return "p";	/* repaint after panning */	if (last_but == 2) {		return "c";	} else if (last_but == 3) {		switch (last_hit) {		case Next:			return "";		case Prev:			return "-1";		case Page:			screenprint("page? ");			return "c";		case Again:			return "p";		case Bigger:			snprint(buf, sizeof buf, "m%g", mag * 1.1);			return buf;		case Smaller:			snprint(buf, sizeof buf, "m%g", mag / 1.1);			return buf;		case Pan:			return pan();		case Quit:			return "q";		default:			return "c";		}	} else {		/* button 1 or bail out */		return "c";	}} static intcheckmouse(void)	/* return button touched if any */{	int c, b;	char *p;	extern int confirm(int); 	b = waitdown();	last_but = 0;	last_hit = -1;	c = 0;	if (button3(b)) {		last_hit = emenuhit(3, &mouse, &mbut3);		last_but = 3;	} else if (button2(b)) {		last_hit = emenuhit(2, &mouse, &mbut2);		last_but = 2;	} else {		/* button1() */		pan();		last_but = 1;	}	waitup();	if (last_but == 3 && last_hit >= 0) {		p = m3[last_hit];		c = p[strlen(p) - 1];	}	if (c == '?' && !confirm(last_but))		last_hit = -1;	return last_but;} Cursor deadmouse = {	{ 0, 0},	/* offset */	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	  0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,	  0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,	  0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	  0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,	  0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,	  0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }}; Cursor blot ={	{ 0, 0 },	{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },	{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }}; Cursor skull ={	{ 0, 0 },	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,	  0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,	  0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,	  0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,	  0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,	  0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,	  0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }}; confirm(int but)	/* ask for confirmation if menu item ends with '?' */{	int c;	static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 }; 	esetcursor(&skull);	c = waitdown();	waitup();	esetcursor(0);	return but == but_cvt[c];}