ref: 45e2b4dfe9570aefe3e5f2a8b7af956b7365f522
dir: /sys/src/cmd/proof/screen.c/
#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 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 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, } }; 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]; }