13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <cursor.h>
57dd7cddfSDavid du Colombier #include <event.h>
63e12c5d1SDavid du Colombier #include <bio.h>
73e12c5d1SDavid du Colombier #include "proof.h"
83e12c5d1SDavid du Colombier
93e12c5d1SDavid du Colombier static int checkmouse(void);
103e12c5d1SDavid du Colombier static int buttondown(void);
113e12c5d1SDavid du Colombier static char *getmousestr(void);
123e12c5d1SDavid du Colombier static char *getkbdstr(int);
133e12c5d1SDavid du Colombier
143e12c5d1SDavid du Colombier extern Cursor blot;
153e12c5d1SDavid du Colombier extern char *track;
163e12c5d1SDavid du Colombier
177dd7cddfSDavid du Colombier Mouse mouse;
187dd7cddfSDavid du Colombier
193e12c5d1SDavid du Colombier void
mapscreen(void)203e12c5d1SDavid du Colombier mapscreen(void)
213e12c5d1SDavid du Colombier {
227dd7cddfSDavid du Colombier if(initdraw(0, 0, "proof") < 0){
237dd7cddfSDavid du Colombier fprint(2, "proof: initdraw failed: %r\n");
247dd7cddfSDavid du Colombier exits("initdraw");
257dd7cddfSDavid du Colombier }
263e12c5d1SDavid du Colombier einit(Ekeyboard|Emouse);
273e12c5d1SDavid du Colombier }
283e12c5d1SDavid du Colombier
293e12c5d1SDavid du Colombier void
clearscreen(void)303e12c5d1SDavid du Colombier clearscreen(void)
313e12c5d1SDavid du Colombier {
327dd7cddfSDavid du Colombier draw(screen, screen->r, display->black, nil, ZP);
333e12c5d1SDavid du Colombier }
343e12c5d1SDavid du Colombier
353e12c5d1SDavid du Colombier void
screenprint(char * fmt,...)363e12c5d1SDavid du Colombier screenprint(char *fmt, ...)
373e12c5d1SDavid du Colombier {
383e12c5d1SDavid du Colombier char buf[100];
393e12c5d1SDavid du Colombier Point p;
403e12c5d1SDavid du Colombier va_list args;
413e12c5d1SDavid du Colombier
423e12c5d1SDavid du Colombier va_start(args, fmt);
439a747e4fSDavid du Colombier vseprint(buf, &buf[sizeof buf], fmt, args);
443e12c5d1SDavid du Colombier va_end(args);
457dd7cddfSDavid du Colombier p = Pt(screen->clipr.min.x+40, screen->clipr.max.y-40);
467dd7cddfSDavid du Colombier string(screen, p, display->black, ZP, font, buf);
473e12c5d1SDavid du Colombier }
483e12c5d1SDavid du Colombier
493e12c5d1SDavid du Colombier #define Viewkey 0xb2
503e12c5d1SDavid du Colombier
513e12c5d1SDavid du Colombier char *
getcmdstr(void)523e12c5d1SDavid du Colombier getcmdstr(void)
533e12c5d1SDavid du Colombier {
543e12c5d1SDavid du Colombier Event ev;
553e12c5d1SDavid du Colombier int e;
56219b2ee8SDavid du Colombier static ulong timekey = 0;
573e12c5d1SDavid du Colombier ulong tracktm = 0;
589a747e4fSDavid du Colombier Dir *dir;
593e12c5d1SDavid du Colombier
603e12c5d1SDavid du Colombier if(track){
61219b2ee8SDavid du Colombier if(timekey == 0)
623e12c5d1SDavid du Colombier timekey = etimer(0, 5000);
639a747e4fSDavid du Colombier dir = dirstat(track);
649a747e4fSDavid du Colombier if(dir != nil){
659a747e4fSDavid du Colombier tracktm = dir->mtime;
669a747e4fSDavid du Colombier free(dir);
679a747e4fSDavid du Colombier }
683e12c5d1SDavid du Colombier }
693e12c5d1SDavid du Colombier for (;;) {
703e12c5d1SDavid du Colombier e = event(&ev);
717dd7cddfSDavid du Colombier if(resized){
727dd7cddfSDavid du Colombier resized = 0;
737dd7cddfSDavid du Colombier return "p";
747dd7cddfSDavid du Colombier }
753e12c5d1SDavid du Colombier if ((e & Emouse) && ev.mouse.buttons) {
763e12c5d1SDavid du Colombier mouse = ev.mouse;
773e12c5d1SDavid du Colombier return getmousestr();
783e12c5d1SDavid du Colombier } else if (e & Ekeyboard)
793e12c5d1SDavid du Colombier return getkbdstr(ev.kbdc); /* sadly, no way to unget */
803e12c5d1SDavid du Colombier else if (e & timekey) {
819a747e4fSDavid du Colombier if((dir = dirstat(track)) != nil){
829a747e4fSDavid du Colombier if(tracktm < dir->mtime){
839a747e4fSDavid du Colombier free(dir);
847dd7cddfSDavid du Colombier return "q";
853e12c5d1SDavid du Colombier }
869a747e4fSDavid du Colombier free(dir);
873e12c5d1SDavid du Colombier }
883e12c5d1SDavid du Colombier }
899a747e4fSDavid du Colombier }
909a747e4fSDavid du Colombier }
913e12c5d1SDavid du Colombier
927dd7cddfSDavid du Colombier static char *
getkbdstr(int c0)933e12c5d1SDavid du Colombier getkbdstr(int c0)
943e12c5d1SDavid du Colombier {
953e12c5d1SDavid du Colombier static char buf[100];
963e12c5d1SDavid du Colombier char *p;
973e12c5d1SDavid du Colombier int c;
983e12c5d1SDavid du Colombier
993e12c5d1SDavid du Colombier if (c0 == '\n')
1003e12c5d1SDavid du Colombier return "";
1013e12c5d1SDavid du Colombier buf[0] = c0;
1023e12c5d1SDavid du Colombier buf[1] = 0;
1033e12c5d1SDavid du Colombier screenprint("%s", buf);
1043e12c5d1SDavid du Colombier for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) {
1053e12c5d1SDavid du Colombier if (c == '\b' && p > buf) {
1063e12c5d1SDavid du Colombier *--p = ' ';
1073e12c5d1SDavid du Colombier } else {
1083e12c5d1SDavid du Colombier *p++ = c;
1093e12c5d1SDavid du Colombier *p = 0;
1103e12c5d1SDavid du Colombier }
1113e12c5d1SDavid du Colombier screenprint("%s", buf);
1123e12c5d1SDavid du Colombier }
1133e12c5d1SDavid du Colombier *p = 0;
1143e12c5d1SDavid du Colombier return buf;
1153e12c5d1SDavid du Colombier }
1163e12c5d1SDavid du Colombier
1173e12c5d1SDavid du Colombier
1183e12c5d1SDavid du Colombier #define button3(b) ((b) & 4)
1193e12c5d1SDavid du Colombier #define button2(b) ((b) & 2)
1203e12c5d1SDavid du Colombier #define button1(b) ((b) & 1)
1213e12c5d1SDavid du Colombier #define button23(b) ((b) & 6)
1223e12c5d1SDavid du Colombier #define button123(b) ((b) & 7)
1233e12c5d1SDavid du Colombier
1243e12c5d1SDavid du Colombier #define butcvt(b) (1 << ((b) - 1))
1253e12c5d1SDavid du Colombier
buttondown(void)1267dd7cddfSDavid du Colombier static int buttondown(void) /* report state of buttons, if any */
1273e12c5d1SDavid du Colombier {
1283e12c5d1SDavid du Colombier if (!ecanmouse()) /* no event pending */
1293e12c5d1SDavid du Colombier return 0;
1303e12c5d1SDavid du Colombier mouse = emouse(); /* something, but it could be motion */
1313e12c5d1SDavid du Colombier return mouse.buttons & 7;
1323e12c5d1SDavid du Colombier }
1333e12c5d1SDavid du Colombier
waitdown(void)1343e12c5d1SDavid du Colombier int waitdown(void) /* wait until some button is down */
1353e12c5d1SDavid du Colombier {
1363e12c5d1SDavid du Colombier while (!(mouse.buttons & 7))
1373e12c5d1SDavid du Colombier mouse = emouse();
1383e12c5d1SDavid du Colombier return mouse.buttons & 7;
1393e12c5d1SDavid du Colombier }
1403e12c5d1SDavid du Colombier
waitup(void)1413e12c5d1SDavid du Colombier int waitup(void)
1423e12c5d1SDavid du Colombier {
1433e12c5d1SDavid du Colombier while (mouse.buttons & 7)
1443e12c5d1SDavid du Colombier mouse = emouse();
1453e12c5d1SDavid du Colombier return mouse.buttons & 7;
1463e12c5d1SDavid du Colombier }
1473e12c5d1SDavid du Colombier
1483e12c5d1SDavid du Colombier char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 };
1493e12c5d1SDavid du Colombier char *m2[] = { 0 };
1503e12c5d1SDavid du Colombier
1513e12c5d1SDavid du Colombier enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit };
1523e12c5d1SDavid du Colombier
1533e12c5d1SDavid du Colombier Menu mbut3 = { m3, 0, 0 };
1543e12c5d1SDavid du Colombier Menu mbut2 = { m2, 0, 0 };
1553e12c5d1SDavid du Colombier
1563e12c5d1SDavid du Colombier int last_hit;
1573e12c5d1SDavid du Colombier int last_but;
1583e12c5d1SDavid du Colombier
pan(void)159219b2ee8SDavid du Colombier char *pan(void)
1603e12c5d1SDavid du Colombier {
161219b2ee8SDavid du Colombier Point dd, xy, lastxy, min, max;
1623e12c5d1SDavid du Colombier
1637dd7cddfSDavid du Colombier esetcursor(&blot);
164219b2ee8SDavid du Colombier waitdown();
165219b2ee8SDavid du Colombier xy = mouse.xy;
166219b2ee8SDavid du Colombier do{
167219b2ee8SDavid du Colombier lastxy = mouse.xy;
168219b2ee8SDavid du Colombier mouse = emouse();
1697dd7cddfSDavid du Colombier dd = subpt(mouse.xy, lastxy);
1707dd7cddfSDavid du Colombier min = addpt(screen->clipr.min, dd);
1717dd7cddfSDavid du Colombier max = addpt(screen->clipr.max, dd);
1727dd7cddfSDavid du Colombier draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)),
1737dd7cddfSDavid du Colombier screen, nil, screen->r.min);
174219b2ee8SDavid du Colombier if(mouse.xy.x < lastxy.x) /* moved left, clear right */
1757dd7cddfSDavid du Colombier draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y),
1767dd7cddfSDavid du Colombier display->white, nil, ZP);
177219b2ee8SDavid du Colombier else /* moved right, clear left*/
1787dd7cddfSDavid du Colombier draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y),
1797dd7cddfSDavid du Colombier display->white, nil, ZP);
180219b2ee8SDavid du Colombier if(mouse.xy.y < lastxy.y) /* moved up, clear down */
1817dd7cddfSDavid du Colombier draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y),
1827dd7cddfSDavid du Colombier display->white, nil, ZP);
183219b2ee8SDavid du Colombier else /* moved down, clear up */
1847dd7cddfSDavid du Colombier draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y),
1857dd7cddfSDavid du Colombier display->white, nil, ZP);
1867dd7cddfSDavid du Colombier flushimage(display, 1);
187219b2ee8SDavid du Colombier }while(mouse.buttons);
1883e12c5d1SDavid du Colombier
1897dd7cddfSDavid du Colombier xyoffset = addpt(xyoffset, subpt(mouse.xy, xy));
1903e12c5d1SDavid du Colombier
1917dd7cddfSDavid du Colombier esetcursor(0);
1923e12c5d1SDavid du Colombier return "p";
1933e12c5d1SDavid du Colombier }
1943e12c5d1SDavid du Colombier
195*bfe6f914SDavid du Colombier static char *
getmousestr(void)196*bfe6f914SDavid du Colombier getmousestr(void)
1973e12c5d1SDavid du Colombier {
198*bfe6f914SDavid du Colombier static char buf[64];
1993e12c5d1SDavid du Colombier
2003e12c5d1SDavid du Colombier checkmouse();
2017dd7cddfSDavid du Colombier if (last_but == 1)
2027dd7cddfSDavid du Colombier return "p"; /* repaint after panning */
2033e12c5d1SDavid du Colombier if (last_but == 2) {
2043e12c5d1SDavid du Colombier return "c";
2053e12c5d1SDavid du Colombier } else if (last_but == 3) {
2063e12c5d1SDavid du Colombier switch (last_hit) {
2073e12c5d1SDavid du Colombier case Next:
2083e12c5d1SDavid du Colombier return "";
2093e12c5d1SDavid du Colombier case Prev:
2103e12c5d1SDavid du Colombier return "-1";
2113e12c5d1SDavid du Colombier case Page:
2123e12c5d1SDavid du Colombier screenprint("page? ");
2133e12c5d1SDavid du Colombier return "c";
2143e12c5d1SDavid du Colombier case Again:
2153e12c5d1SDavid du Colombier return "p";
2163e12c5d1SDavid du Colombier case Bigger:
217*bfe6f914SDavid du Colombier snprint(buf, sizeof buf, "m%g", mag * 1.1);
2183e12c5d1SDavid du Colombier return buf;
2193e12c5d1SDavid du Colombier case Smaller:
220*bfe6f914SDavid du Colombier snprint(buf, sizeof buf, "m%g", mag / 1.1);
2213e12c5d1SDavid du Colombier return buf;
2223e12c5d1SDavid du Colombier case Pan:
223219b2ee8SDavid du Colombier return pan();
2243e12c5d1SDavid du Colombier case Quit:
2253e12c5d1SDavid du Colombier return "q";
2263e12c5d1SDavid du Colombier default:
2273e12c5d1SDavid du Colombier return "c";
2283e12c5d1SDavid du Colombier }
2293e12c5d1SDavid du Colombier } else { /* button 1 or bail out */
2303e12c5d1SDavid du Colombier return "c";
2313e12c5d1SDavid du Colombier }
2323e12c5d1SDavid du Colombier }
2333e12c5d1SDavid du Colombier
2347dd7cddfSDavid du Colombier static int
checkmouse(void)2353e12c5d1SDavid du Colombier checkmouse(void) /* return button touched if any */
2363e12c5d1SDavid du Colombier {
2373e12c5d1SDavid du Colombier int c, b;
2383e12c5d1SDavid du Colombier char *p;
2393e12c5d1SDavid du Colombier extern int confirm(int);
2403e12c5d1SDavid du Colombier
2413e12c5d1SDavid du Colombier b = waitdown();
2423e12c5d1SDavid du Colombier last_but = 0;
2433e12c5d1SDavid du Colombier last_hit = -1;
2443e12c5d1SDavid du Colombier c = 0;
2453e12c5d1SDavid du Colombier if (button3(b)) {
2467dd7cddfSDavid du Colombier last_hit = emenuhit(3, &mouse, &mbut3);
2473e12c5d1SDavid du Colombier last_but = 3;
2483e12c5d1SDavid du Colombier } else if (button2(b)) {
2497dd7cddfSDavid du Colombier last_hit = emenuhit(2, &mouse, &mbut2);
2503e12c5d1SDavid du Colombier last_but = 2;
2513e12c5d1SDavid du Colombier } else { /* button1() */
2527dd7cddfSDavid du Colombier pan();
2533e12c5d1SDavid du Colombier last_but = 1;
2543e12c5d1SDavid du Colombier }
2553e12c5d1SDavid du Colombier waitup();
2563e12c5d1SDavid du Colombier if (last_but == 3 && last_hit >= 0) {
2573e12c5d1SDavid du Colombier p = m3[last_hit];
2583e12c5d1SDavid du Colombier c = p[strlen(p) - 1];
2593e12c5d1SDavid du Colombier }
2603e12c5d1SDavid du Colombier if (c == '?' && !confirm(last_but))
2613e12c5d1SDavid du Colombier last_hit = -1;
2623e12c5d1SDavid du Colombier return last_but;
2633e12c5d1SDavid du Colombier }
2643e12c5d1SDavid du Colombier
2653e12c5d1SDavid du Colombier Cursor deadmouse = {
2663e12c5d1SDavid du Colombier { 0, 0}, /* offset */
2673e12c5d1SDavid du Colombier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2683e12c5d1SDavid du Colombier 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
2693e12c5d1SDavid du Colombier 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
2703e12c5d1SDavid du Colombier 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
2713e12c5d1SDavid du Colombier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2723e12c5d1SDavid du Colombier 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
2733e12c5d1SDavid du Colombier 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
2743e12c5d1SDavid du Colombier 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
2753e12c5d1SDavid du Colombier };
2763e12c5d1SDavid du Colombier
2773e12c5d1SDavid du Colombier Cursor blot ={
2783e12c5d1SDavid du Colombier { 0, 0 },
2793e12c5d1SDavid du Colombier { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2803e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2813e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2823e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
2833e12c5d1SDavid du Colombier { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2843e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2853e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2863e12c5d1SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
2873e12c5d1SDavid du Colombier };
2883e12c5d1SDavid du Colombier
2893e12c5d1SDavid du Colombier Cursor skull ={
2903e12c5d1SDavid du Colombier { 0, 0 },
2913e12c5d1SDavid du Colombier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
2923e12c5d1SDavid du Colombier 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
2933e12c5d1SDavid du Colombier 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
2943e12c5d1SDavid du Colombier 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
2953e12c5d1SDavid du Colombier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
2963e12c5d1SDavid du Colombier 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
2973e12c5d1SDavid du Colombier 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
2983e12c5d1SDavid du Colombier 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
2993e12c5d1SDavid du Colombier };
3003e12c5d1SDavid du Colombier
confirm(int but)3013e12c5d1SDavid du Colombier confirm(int but) /* ask for confirmation if menu item ends with '?' */
3023e12c5d1SDavid du Colombier {
3033e12c5d1SDavid du Colombier int c;
3043e12c5d1SDavid du Colombier static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 };
3053e12c5d1SDavid du Colombier
3067dd7cddfSDavid du Colombier esetcursor(&skull);
3073e12c5d1SDavid du Colombier c = waitdown();
3083e12c5d1SDavid du Colombier waitup();
3097dd7cddfSDavid du Colombier esetcursor(0);
3103e12c5d1SDavid du Colombier return but == but_cvt[c];
3113e12c5d1SDavid du Colombier }
312