plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

screen.c (6692B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <draw.h>
      4 #include <cursor.h>
      5 #include <event.h>
      6 #include <bio.h>
      7 #include "proof.h"
      8 
      9 static	int	checkmouse(void);
     10 /* static	int	buttondown(void); */
     11 static	char	*getmousestr(void);
     12 static	char	*getkbdstr(int);
     13 
     14 extern	Cursor	blot;
     15 extern	char	*track;
     16 
     17 Mouse	mouse;
     18 
     19 void
     20 mapscreen(void)
     21 {
     22 	if(initdraw(0, 0, "proof") < 0){
     23 		fprint(2, "proof: initdraw failed: %r\n");
     24 		exits("initdraw");
     25 	}
     26 	einit(Ekeyboard|Emouse);
     27 }
     28 
     29 void
     30 clearscreen(void)
     31 {
     32 	draw(screen, screen->r, display->black, nil, ZP);
     33 }
     34 
     35 void
     36 screenprint(char *fmt, ...)
     37 {
     38 	char buf[100];
     39 	Point p;
     40 	va_list args;
     41 
     42 	va_start(args, fmt);
     43 	vseprint(buf, &buf[sizeof buf], fmt, args);
     44 	va_end(args);
     45 	p = Pt(screen->clipr.min.x+40, screen->clipr.max.y-40);
     46 	string(screen, p, display->black, ZP, font, buf);
     47 }
     48 
     49 #define	Viewkey	0xb2
     50 #define etimer(x, y) 0
     51 
     52 char *
     53 getcmdstr(void)
     54 {
     55 	Event ev;
     56 	int e;
     57 	static ulong timekey = 0;
     58 	ulong tracktm = 0;
     59 	Dir *dir;
     60 
     61 	if(track){
     62 		if(timekey == 0)
     63 			timekey = etimer(0, 5000);
     64 		dir = dirstat(track);
     65 		if(dir != nil){
     66 			tracktm = dir->mtime;
     67 			free(dir);
     68 		}
     69 	}
     70 	for (;;) {
     71 		e = event(&ev);
     72 		if(resized){
     73 			resized = 0;
     74 			return "p";
     75 		}
     76 		if ((e & Emouse) && ev.mouse.buttons) {
     77 			mouse = ev.mouse;
     78 			return getmousestr();
     79 		} else if (e & Ekeyboard)
     80 			return getkbdstr(ev.kbdc);	/* sadly, no way to unget */
     81 		else if (e & timekey) {
     82 			if((dir = dirstat(track)) != nil){
     83 				if(tracktm < dir->mtime){
     84 					free(dir);
     85 					return "q";
     86 				}
     87 				free(dir);
     88 			}
     89 		}
     90 	}
     91 }
     92 
     93 static char *
     94 getkbdstr(int c0)
     95 {
     96 	static char buf[100];
     97 	char *p;
     98 	int c;
     99 
    100 	if (c0 == '\n')
    101 		return "";
    102 	buf[0] = c0;
    103 	buf[1] = 0;
    104 	screenprint("%s", buf);
    105 	for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) {
    106 		if (c == '\b' && p > buf) {
    107 			*--p = ' ';
    108 		} else {
    109 			*p++ = c;
    110 			*p = 0;
    111 		}
    112 		screenprint("%s", buf);
    113 	}
    114 	*p = 0;
    115 	return buf;
    116 }
    117 
    118 
    119 #define button3(b)	((b) & 4)
    120 #define button2(b)	((b) & 2)
    121 #define button1(b)	((b) & 1)
    122 #define button23(b)	((b) & 6)
    123 #define button123(b)	((b) & 7)
    124 
    125 #define	butcvt(b)	(1 << ((b) - 1))
    126 
    127 #if 0
    128 static int buttondown(void)	/* report state of buttons, if any */
    129 {
    130 	if (!ecanmouse())	/* no event pending */
    131 		return 0;
    132 	mouse = emouse();	/* something, but it could be motion */
    133 	return mouse.buttons & 7;
    134 }
    135 #endif
    136 
    137 int waitdown(void)	/* wait until some button is down */
    138 {
    139 	while (!(mouse.buttons & 7))
    140 		mouse = emouse();
    141 	return mouse.buttons & 7;
    142 }
    143 
    144 int waitup(void)
    145 {
    146 	while (mouse.buttons & 7)
    147 		mouse = emouse();
    148 	return mouse.buttons & 7;
    149 }
    150 
    151 char *m3[]	= { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 };
    152 char *m2[]	= { 0 };
    153 
    154 enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit };
    155 
    156 Menu	mbut3	= { m3, 0, 0 };
    157 Menu	mbut2	= { m2, 0, 0 };
    158 
    159 int	last_hit;
    160 int	last_but;
    161 
    162 char *pan(void)
    163 {
    164 	Point dd, xy, lastxy, min, max;
    165 
    166 	esetcursor(&blot);
    167 	waitdown();
    168 	xy = mouse.xy;
    169 	do{
    170 		lastxy = mouse.xy;
    171 		mouse = emouse();
    172 		dd = subpt(mouse.xy, lastxy);
    173 		min = addpt(screen->clipr.min, dd);
    174 		max = addpt(screen->clipr.max, dd);
    175 		draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)),
    176 			screen, nil, screen->r.min);
    177 		if(mouse.xy.x < lastxy.x)	/* moved left, clear right */
    178 			draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y),
    179 				display->white, nil, ZP);
    180 		else	/* moved right, clear left*/
    181 			draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y),
    182 				display->white, nil, ZP);
    183 		if(mouse.xy.y < lastxy.y)	/* moved up, clear down */
    184 			draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y),
    185 				display->white, nil, ZP);
    186 		else		/* moved down, clear up */
    187 			draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y),
    188 				display->white, nil, ZP);
    189 		flushimage(display, 1);
    190 	}while(mouse.buttons);
    191 
    192 	xyoffset = addpt(xyoffset, subpt(mouse.xy, xy));
    193 
    194 	esetcursor(0);
    195 	return "p";
    196 }
    197 
    198 static char *getmousestr(void)
    199 {
    200 	static char buf[20];
    201 
    202 	checkmouse();
    203 	if (last_but == 1)
    204 		return "p";	/* repaint after panning */
    205 	if (last_but == 2) {
    206 		return "c";
    207 	} else if (last_but == 3) {
    208 		switch (last_hit) {
    209 		case Next:
    210 			return "";
    211 		case Prev:
    212 			return "-1";
    213 		case Page:
    214 			screenprint("page? ");
    215 			return "c";
    216 		case Again:
    217 			return "p";
    218 		case Bigger:
    219 			sprint(buf, "m%g", mag * 1.1);
    220 			return buf;
    221 		case Smaller:
    222 			sprint(buf, "m%g", mag / 1.1);
    223 			return buf;
    224 		case Pan:
    225 			return pan();
    226 		case Quit:
    227 			return "q";
    228 		default:
    229 			return "c";
    230 		}
    231 	} else {		/* button 1 or bail out */
    232 		return "c";
    233 	}
    234 }
    235 
    236 static int
    237 checkmouse(void)	/* return button touched if any */
    238 {
    239 	int c, b;
    240 	char *p;
    241 	extern int confirm(int);
    242 
    243 	b = waitdown();
    244 	last_but = 0;
    245 	last_hit = -1;
    246 	c = 0;
    247 	if (button3(b)) {
    248 		last_hit = emenuhit(3, &mouse, &mbut3);
    249 		last_but = 3;
    250 	} else if (button2(b)) {
    251 		last_hit = emenuhit(2, &mouse, &mbut2);
    252 		last_but = 2;
    253 	} else {		/* button1() */
    254 		pan();
    255 		last_but = 1;
    256 	}
    257 	waitup();
    258 	if (last_but == 3 && last_hit >= 0) {
    259 		p = m3[last_hit];
    260 		c = p[strlen(p) - 1];
    261 	}
    262 	if (c == '?' && !confirm(last_but))
    263 		last_hit = -1;
    264 	return last_but;
    265 }
    266 
    267 Cursor deadmouse = {
    268 	{ 0, 0},	/* offset */
    269 	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    270 	  0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
    271 	  0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
    272 	  0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    273 	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    274 	  0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
    275 	  0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
    276 	  0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
    277 };
    278 
    279 Cursor blot ={
    280 	{ 0, 0 },
    281 	{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    282 	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    283 	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    284 	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
    285 	{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    286 	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    287 	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    288 	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
    289 };
    290 
    291 Cursor skull ={
    292 	{ 0, 0 },
    293 	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
    294 	  0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
    295 	  0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
    296 	  0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    297 	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
    298 	  0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
    299 	  0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
    300 	  0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
    301 };
    302 
    303 int
    304 confirm(int but)	/* ask for confirmation if menu item ends with '?' */
    305 {
    306 	int c;
    307 	static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 };
    308 
    309 	esetcursor(&skull);
    310 	c = waitdown();
    311 	waitup();
    312 	esetcursor(0);
    313 	return but == but_cvt[c];
    314 }