13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libg.h> 33e12c5d1SDavid du Colombier #include <libc.h> 43e12c5d1SDavid du Colombier #include <stdarg.h> 53e12c5d1SDavid du Colombier #include <bio.h> 63e12c5d1SDavid du Colombier #include "proof.h" 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier Bitmap screen; 93e12c5d1SDavid du Colombier Mouse mouse; 103e12c5d1SDavid du Colombier 113e12c5d1SDavid du Colombier static int checkmouse(void); 123e12c5d1SDavid du Colombier static int buttondown(void); 133e12c5d1SDavid du Colombier static char *getmousestr(void); 143e12c5d1SDavid du Colombier static char *getkbdstr(int); 153e12c5d1SDavid du Colombier 163e12c5d1SDavid du Colombier extern Cursor blot; 173e12c5d1SDavid du Colombier extern char *track; 183e12c5d1SDavid du Colombier 193e12c5d1SDavid du Colombier void 203e12c5d1SDavid du Colombier mapscreen(void) 213e12c5d1SDavid du Colombier { 223e12c5d1SDavid du Colombier binit(0, 0, "proof"); 233e12c5d1SDavid du Colombier einit(Ekeyboard|Emouse); 243e12c5d1SDavid du Colombier } 253e12c5d1SDavid du Colombier 263e12c5d1SDavid du Colombier void 273e12c5d1SDavid du Colombier clearscreen(void) 283e12c5d1SDavid du Colombier { 293e12c5d1SDavid du Colombier bitblt(&screen, screen.r.min, &screen, screen.r, 0); 303e12c5d1SDavid du Colombier } 313e12c5d1SDavid du Colombier 323e12c5d1SDavid du Colombier void 333e12c5d1SDavid du Colombier screenprint(char *fmt, ...) 343e12c5d1SDavid du Colombier { 353e12c5d1SDavid du Colombier char buf[100]; 363e12c5d1SDavid du Colombier Point p; 373e12c5d1SDavid du Colombier va_list args; 383e12c5d1SDavid du Colombier 393e12c5d1SDavid du Colombier va_start(args, fmt); 403e12c5d1SDavid du Colombier doprint(buf, &buf[sizeof buf], fmt, args); 413e12c5d1SDavid du Colombier va_end(args); 42*219b2ee8SDavid du Colombier p = Pt(screen.clipr.min.x+40, screen.clipr.max.y-40); 433e12c5d1SDavid du Colombier string(&screen, p, font, buf, S); 443e12c5d1SDavid du Colombier } 453e12c5d1SDavid du Colombier 463e12c5d1SDavid du Colombier 473e12c5d1SDavid du Colombier #define Viewkey 0xb2 483e12c5d1SDavid du Colombier 493e12c5d1SDavid du Colombier char * 503e12c5d1SDavid du Colombier getcmdstr(void) 513e12c5d1SDavid du Colombier { 523e12c5d1SDavid du Colombier Event ev; 533e12c5d1SDavid du Colombier int e; 54*219b2ee8SDavid du Colombier static ulong timekey = 0; 553e12c5d1SDavid du Colombier ulong tracktm = 0; 563e12c5d1SDavid du Colombier Dir dir; 573e12c5d1SDavid du Colombier 583e12c5d1SDavid du Colombier if(track){ 59*219b2ee8SDavid du Colombier if(timekey == 0) 603e12c5d1SDavid du Colombier timekey = etimer(0, 5000); 613e12c5d1SDavid du Colombier if(dirstat(track, &dir) >= 0) 623e12c5d1SDavid du Colombier tracktm = dir.mtime; 633e12c5d1SDavid du Colombier } 643e12c5d1SDavid du Colombier for (;;) { 653e12c5d1SDavid du Colombier e = event(&ev); 663e12c5d1SDavid du Colombier if ((e & Emouse) && ev.mouse.buttons) { 673e12c5d1SDavid du Colombier mouse = ev.mouse; 683e12c5d1SDavid du Colombier return getmousestr(); 693e12c5d1SDavid du Colombier } else if (e & Ekeyboard) 703e12c5d1SDavid du Colombier return getkbdstr(ev.kbdc); /* sadly, no way to unget */ 713e12c5d1SDavid du Colombier else if (e & timekey) { 723e12c5d1SDavid du Colombier if((dirstat(track, &dir) >= 0) && (tracktm < dir.mtime)) 733e12c5d1SDavid du Colombier return "q\n"; 743e12c5d1SDavid du Colombier } 753e12c5d1SDavid du Colombier } 763e12c5d1SDavid du Colombier } 773e12c5d1SDavid du Colombier 783e12c5d1SDavid du Colombier char * 793e12c5d1SDavid du Colombier getkbdstr(int c0) 803e12c5d1SDavid du Colombier { 813e12c5d1SDavid du Colombier static char buf[100]; 823e12c5d1SDavid du Colombier char *p; 833e12c5d1SDavid du Colombier int c; 843e12c5d1SDavid du Colombier 853e12c5d1SDavid du Colombier if (c0 == '\n') 863e12c5d1SDavid du Colombier return ""; 873e12c5d1SDavid du Colombier buf[0] = c0; 883e12c5d1SDavid du Colombier buf[1] = 0; 893e12c5d1SDavid du Colombier screenprint("%s", buf); 903e12c5d1SDavid du Colombier for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) { 913e12c5d1SDavid du Colombier if (c == '\b' && p > buf) { 923e12c5d1SDavid du Colombier *--p = ' '; 933e12c5d1SDavid du Colombier } else { 943e12c5d1SDavid du Colombier *p++ = c; 953e12c5d1SDavid du Colombier *p = 0; 963e12c5d1SDavid du Colombier } 973e12c5d1SDavid du Colombier screenprint("%s", buf); 983e12c5d1SDavid du Colombier } 993e12c5d1SDavid du Colombier *p = 0; 1003e12c5d1SDavid du Colombier return buf; 1013e12c5d1SDavid du Colombier } 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier 1043e12c5d1SDavid du Colombier #define button3(b) ((b) & 4) 1053e12c5d1SDavid du Colombier #define button2(b) ((b) & 2) 1063e12c5d1SDavid du Colombier #define button1(b) ((b) & 1) 1073e12c5d1SDavid du Colombier #define button23(b) ((b) & 6) 1083e12c5d1SDavid du Colombier #define button123(b) ((b) & 7) 1093e12c5d1SDavid du Colombier 1103e12c5d1SDavid du Colombier #define butcvt(b) (1 << ((b) - 1)) 1113e12c5d1SDavid du Colombier 1123e12c5d1SDavid du Colombier int buttondown(void) /* report state of buttons, if any */ 1133e12c5d1SDavid du Colombier { 1143e12c5d1SDavid du Colombier if (!ecanmouse()) /* no event pending */ 1153e12c5d1SDavid du Colombier return 0; 1163e12c5d1SDavid du Colombier mouse = emouse(); /* something, but it could be motion */ 1173e12c5d1SDavid du Colombier return mouse.buttons & 7; 1183e12c5d1SDavid du Colombier } 1193e12c5d1SDavid du Colombier 1203e12c5d1SDavid du Colombier int waitdown(void) /* wait until some button is down */ 1213e12c5d1SDavid du Colombier { 1223e12c5d1SDavid du Colombier while (!(mouse.buttons & 7)) 1233e12c5d1SDavid du Colombier mouse = emouse(); 1243e12c5d1SDavid du Colombier return mouse.buttons & 7; 1253e12c5d1SDavid du Colombier } 1263e12c5d1SDavid du Colombier 1273e12c5d1SDavid du Colombier int waitup(void) 1283e12c5d1SDavid du Colombier { 1293e12c5d1SDavid du Colombier while (mouse.buttons & 7) 1303e12c5d1SDavid du Colombier mouse = emouse(); 1313e12c5d1SDavid du Colombier return mouse.buttons & 7; 1323e12c5d1SDavid du Colombier } 1333e12c5d1SDavid du Colombier 1343e12c5d1SDavid du Colombier char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 }; 1353e12c5d1SDavid du Colombier char *m2[] = { 0 }; 1363e12c5d1SDavid du Colombier 1373e12c5d1SDavid du Colombier enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit }; 1383e12c5d1SDavid du Colombier 1393e12c5d1SDavid du Colombier Menu mbut3 = { m3, 0, 0 }; 1403e12c5d1SDavid du Colombier Menu mbut2 = { m2, 0, 0 }; 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier int last_hit; 1433e12c5d1SDavid du Colombier int last_but; 1443e12c5d1SDavid du Colombier 145*219b2ee8SDavid du Colombier char *pan(void) 1463e12c5d1SDavid du Colombier { 147*219b2ee8SDavid du Colombier Point dd, xy, lastxy, min, max; 1483e12c5d1SDavid du Colombier 1493e12c5d1SDavid du Colombier cursorswitch(&blot); 150*219b2ee8SDavid du Colombier waitdown(); 151*219b2ee8SDavid du Colombier xy = mouse.xy; 152*219b2ee8SDavid du Colombier do{ 153*219b2ee8SDavid du Colombier lastxy = mouse.xy; 154*219b2ee8SDavid du Colombier mouse = emouse(); 155*219b2ee8SDavid du Colombier dd = sub(mouse.xy, lastxy); 156*219b2ee8SDavid du Colombier min = add(screen.clipr.min, dd); 157*219b2ee8SDavid du Colombier max = add(screen.clipr.max, dd); 158*219b2ee8SDavid du Colombier bitblt(&screen, add(screen.r.min, sub(mouse.xy, lastxy)), &screen, screen.r, S); 159*219b2ee8SDavid du Colombier if(mouse.xy.x < lastxy.x) /* moved left, clear right */ 160*219b2ee8SDavid du Colombier bitblt(&screen, Pt(max.x, screen.r.min.y), &screen, 161*219b2ee8SDavid du Colombier Rect(max.x, screen.r.min.y, screen.r.max.x, screen.r.max.y), 0); 162*219b2ee8SDavid du Colombier else /* moved right, clear left*/ 163*219b2ee8SDavid du Colombier bitblt(&screen, screen.r.min, &screen, 164*219b2ee8SDavid du Colombier Rect(screen.r.min.x, screen.r.min.y, min.x, screen.r.max.y), 0); 165*219b2ee8SDavid du Colombier if(mouse.xy.y < lastxy.y) /* moved up, clear down */ 166*219b2ee8SDavid du Colombier bitblt(&screen, Pt(screen.r.min.x, max.y), &screen, 167*219b2ee8SDavid du Colombier Rect(screen.r.min.x, max.y, screen.r.max.x, screen.r.max.y), 0); 168*219b2ee8SDavid du Colombier else /* moved down, clear up */ 169*219b2ee8SDavid du Colombier bitblt(&screen, screen.r.min, &screen, 170*219b2ee8SDavid du Colombier Rect(screen.r.min.x, screen.r.min.y, screen.r.max.x, min.y), 0); 171*219b2ee8SDavid du Colombier bflush(); 172*219b2ee8SDavid du Colombier }while(mouse.buttons); 1733e12c5d1SDavid du Colombier 174*219b2ee8SDavid du Colombier xyoffset = add(xyoffset, sub(mouse.xy, xy)); 1753e12c5d1SDavid du Colombier 1763e12c5d1SDavid du Colombier cursorswitch(0); 1773e12c5d1SDavid du Colombier return "p"; 1783e12c5d1SDavid du Colombier } 1793e12c5d1SDavid du Colombier 1803e12c5d1SDavid du Colombier char *getmousestr(void) 1813e12c5d1SDavid du Colombier { 1823e12c5d1SDavid du Colombier static char buf[20]; 1833e12c5d1SDavid du Colombier 1843e12c5d1SDavid du Colombier checkmouse(); 1853e12c5d1SDavid du Colombier if (last_but == 2) { 1863e12c5d1SDavid du Colombier return "c"; 1873e12c5d1SDavid du Colombier } else if (last_but == 3) { 1883e12c5d1SDavid du Colombier switch (last_hit) { 1893e12c5d1SDavid du Colombier case Next: 1903e12c5d1SDavid du Colombier return ""; 1913e12c5d1SDavid du Colombier case Prev: 1923e12c5d1SDavid du Colombier return "-1"; 1933e12c5d1SDavid du Colombier case Page: 1943e12c5d1SDavid du Colombier screenprint("page? "); 1953e12c5d1SDavid du Colombier return "c"; 1963e12c5d1SDavid du Colombier case Again: 1973e12c5d1SDavid du Colombier return "p"; 1983e12c5d1SDavid du Colombier case Bigger: 1993e12c5d1SDavid du Colombier sprint(buf, "m%g", mag * 1.1); 2003e12c5d1SDavid du Colombier return buf; 2013e12c5d1SDavid du Colombier case Smaller: 2023e12c5d1SDavid du Colombier sprint(buf, "m%g", mag / 1.1); 2033e12c5d1SDavid du Colombier return buf; 2043e12c5d1SDavid du Colombier case Pan: 205*219b2ee8SDavid du Colombier return pan(); 2063e12c5d1SDavid du Colombier case Quit: 2073e12c5d1SDavid du Colombier return "q"; 2083e12c5d1SDavid du Colombier default: 2093e12c5d1SDavid du Colombier return "c"; 2103e12c5d1SDavid du Colombier } 2113e12c5d1SDavid du Colombier } else { /* button 1 or bail out */ 2123e12c5d1SDavid du Colombier return "c"; 2133e12c5d1SDavid du Colombier } 2143e12c5d1SDavid du Colombier } 2153e12c5d1SDavid du Colombier 2163e12c5d1SDavid du Colombier int 2173e12c5d1SDavid du Colombier checkmouse(void) /* return button touched if any */ 2183e12c5d1SDavid du Colombier { 2193e12c5d1SDavid du Colombier int c, b; 2203e12c5d1SDavid du Colombier char *p; 2213e12c5d1SDavid du Colombier extern int confirm(int); 2223e12c5d1SDavid du Colombier 2233e12c5d1SDavid du Colombier b = waitdown(); 2243e12c5d1SDavid du Colombier last_but = 0; 2253e12c5d1SDavid du Colombier last_hit = -1; 2263e12c5d1SDavid du Colombier c = 0; 2273e12c5d1SDavid du Colombier if (button3(b)) { 2283e12c5d1SDavid du Colombier last_hit = menuhit(3, &mouse, &mbut3); 2293e12c5d1SDavid du Colombier last_but = 3; 2303e12c5d1SDavid du Colombier } else if (button2(b)) { 2313e12c5d1SDavid du Colombier last_hit = menuhit(2, &mouse, &mbut2); 2323e12c5d1SDavid du Colombier last_but = 2; 2333e12c5d1SDavid du Colombier } else { /* button1() */ 2343e12c5d1SDavid du Colombier last_but = 1; 2353e12c5d1SDavid du Colombier } 2363e12c5d1SDavid du Colombier waitup(); 2373e12c5d1SDavid du Colombier if (last_but == 3 && last_hit >= 0) { 2383e12c5d1SDavid du Colombier p = m3[last_hit]; 2393e12c5d1SDavid du Colombier c = p[strlen(p) - 1]; 2403e12c5d1SDavid du Colombier } 2413e12c5d1SDavid du Colombier if (c == '?' && !confirm(last_but)) 2423e12c5d1SDavid du Colombier last_hit = -1; 2433e12c5d1SDavid du Colombier return last_but; 2443e12c5d1SDavid du Colombier } 2453e12c5d1SDavid du Colombier 2463e12c5d1SDavid du Colombier Cursor deadmouse = { 2473e12c5d1SDavid du Colombier { 0, 0}, /* offset */ 2483e12c5d1SDavid du Colombier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2493e12c5d1SDavid du Colombier 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41, 2503e12c5d1SDavid du Colombier 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0, 2513e12c5d1SDavid du Colombier 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 2523e12c5d1SDavid du Colombier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2533e12c5d1SDavid du Colombier 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41, 2543e12c5d1SDavid du Colombier 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0, 2553e12c5d1SDavid du Colombier 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } 2563e12c5d1SDavid du Colombier }; 2573e12c5d1SDavid du Colombier 2583e12c5d1SDavid du Colombier Cursor blot ={ 2593e12c5d1SDavid du Colombier { 0, 0 }, 2603e12c5d1SDavid du Colombier { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2613e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2623e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2633e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, 2643e12c5d1SDavid du Colombier { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2653e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2663e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2673e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, } 2683e12c5d1SDavid du Colombier }; 2693e12c5d1SDavid du Colombier 2703e12c5d1SDavid du Colombier Cursor skull ={ 2713e12c5d1SDavid du Colombier { 0, 0 }, 2723e12c5d1SDavid du Colombier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 2733e12c5d1SDavid du Colombier 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0, 2743e12c5d1SDavid du Colombier 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27, 2753e12c5d1SDavid du Colombier 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 2763e12c5d1SDavid du Colombier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 2773e12c5d1SDavid du Colombier 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0, 2783e12c5d1SDavid du Colombier 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27, 2793e12c5d1SDavid du Colombier 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } 2803e12c5d1SDavid du Colombier }; 2813e12c5d1SDavid du Colombier 2823e12c5d1SDavid du Colombier confirm(int but) /* ask for confirmation if menu item ends with '?' */ 2833e12c5d1SDavid du Colombier { 2843e12c5d1SDavid du Colombier int c; 2853e12c5d1SDavid du Colombier static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 }; 2863e12c5d1SDavid du Colombier 2873e12c5d1SDavid du Colombier cursorswitch(&skull); 2883e12c5d1SDavid du Colombier c = waitdown(); 2893e12c5d1SDavid du Colombier waitup(); 2903e12c5d1SDavid du Colombier cursorswitch(0); 2913e12c5d1SDavid du Colombier return but == but_cvt[c]; 2923e12c5d1SDavid du Colombier } 293