| #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; |
| |
| void |
| mapscreen(void) |
| { |
| if(initdraw(0, 0, "proof") < 0){ |
| fprint(2, "proof: initdraw failed: %r\n"); |
| exits("initdraw"); |
| } |
| einit(Ekeyboard|Emouse); |
| } |
| |
| void |
| clearscreen(void) |
| { |
| draw(screen, screen->r, display->black, nil, ZP); |
| } |
| |
| void |
| screenprint(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 |
| #define etimer(x, y) 0 |
| |
| 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)) |
| |
| #if 0 |
| 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; |
| } |
| #endif |
| |
| 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[20]; |
| |
| 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: |
| sprint(buf, "m%g", mag * 1.1); |
| return buf; |
| case Smaller: |
| sprint(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 int |
| checkmouse(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, } |
| }; |
| |
| int |
| 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]; |
| } |