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 51 char * 52 getcmdstr(void) 53 { 54 Event ev; 55 int e; 56 static ulong timekey = 0; 57 ulong tracktm = 0; 58 Dir *dir; 59 60 if(track){ 61 if(timekey == 0) 62 timekey = etimer(0, 5000); 63 dir = dirstat(track); 64 if(dir != nil){ 65 tracktm = dir->mtime; 66 free(dir); 67 } 68 } 69 for (;;) { 70 e = event(&ev); 71 if(resized){ 72 resized = 0; 73 return "p"; 74 } 75 if ((e & Emouse) && ev.mouse.buttons) { 76 mouse = ev.mouse; 77 return getmousestr(); 78 } else if (e & Ekeyboard) 79 return getkbdstr(ev.kbdc); /* sadly, no way to unget */ 80 else if (e & timekey) { 81 if((dir = dirstat(track)) != nil){ 82 if(tracktm < dir->mtime){ 83 free(dir); 84 return "q"; 85 } 86 free(dir); 87 } 88 } 89 } 90 return nil; 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 static int buttondown(void) /* report state of buttons, if any */ 128 { 129 if (!ecanmouse()) /* no event pending */ 130 return 0; 131 mouse = emouse(); /* something, but it could be motion */ 132 return mouse.buttons & 7; 133 } 134 135 int waitdown(void) /* wait until some button is down */ 136 { 137 while (!(mouse.buttons & 7)) 138 mouse = emouse(); 139 return mouse.buttons & 7; 140 } 141 142 int waitup(void) 143 { 144 while (mouse.buttons & 7) 145 mouse = emouse(); 146 return mouse.buttons & 7; 147 } 148 149 char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 }; 150 char *m2[] = { 0 }; 151 152 enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit }; 153 154 Menu mbut3 = { m3, 0, 0 }; 155 Menu mbut2 = { m2, 0, 0 }; 156 157 int last_hit; 158 int last_but; 159 160 char *pan(void) 161 { 162 Point dd, xy, lastxy, min, max; 163 164 esetcursor(&blot); 165 waitdown(); 166 xy = mouse.xy; 167 do{ 168 lastxy = mouse.xy; 169 mouse = emouse(); 170 dd = subpt(mouse.xy, lastxy); 171 min = addpt(screen->clipr.min, dd); 172 max = addpt(screen->clipr.max, dd); 173 draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)), 174 screen, nil, screen->r.min); 175 if(mouse.xy.x < lastxy.x) /* moved left, clear right */ 176 draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y), 177 display->white, nil, ZP); 178 else /* moved right, clear left*/ 179 draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y), 180 display->white, nil, ZP); 181 if(mouse.xy.y < lastxy.y) /* moved up, clear down */ 182 draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y), 183 display->white, nil, ZP); 184 else /* moved down, clear up */ 185 draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y), 186 display->white, nil, ZP); 187 flushimage(display, 1); 188 }while(mouse.buttons); 189 190 xyoffset = addpt(xyoffset, subpt(mouse.xy, xy)); 191 192 esetcursor(0); 193 return "p"; 194 } 195 196 static char *getmousestr(void) 197 { 198 static char buf[20]; 199 200 checkmouse(); 201 if (last_but == 1) 202 return "p"; /* repaint after panning */ 203 if (last_but == 2) { 204 return "c"; 205 } else if (last_but == 3) { 206 switch (last_hit) { 207 case Next: 208 return ""; 209 case Prev: 210 return "-1"; 211 case Page: 212 screenprint("page? "); 213 return "c"; 214 case Again: 215 return "p"; 216 case Bigger: 217 sprint(buf, "m%g", mag * 1.1); 218 return buf; 219 case Smaller: 220 sprint(buf, "m%g", mag / 1.1); 221 return buf; 222 case Pan: 223 return pan(); 224 case Quit: 225 return "q"; 226 default: 227 return "c"; 228 } 229 } else { /* button 1 or bail out */ 230 return "c"; 231 } 232 } 233 234 static int 235 checkmouse(void) /* return button touched if any */ 236 { 237 int c, b; 238 char *p; 239 extern int confirm(int); 240 241 b = waitdown(); 242 last_but = 0; 243 last_hit = -1; 244 c = 0; 245 if (button3(b)) { 246 last_hit = emenuhit(3, &mouse, &mbut3); 247 last_but = 3; 248 } else if (button2(b)) { 249 last_hit = emenuhit(2, &mouse, &mbut2); 250 last_but = 2; 251 } else { /* button1() */ 252 pan(); 253 last_but = 1; 254 } 255 waitup(); 256 if (last_but == 3 && last_hit >= 0) { 257 p = m3[last_hit]; 258 c = p[strlen(p) - 1]; 259 } 260 if (c == '?' && !confirm(last_but)) 261 last_hit = -1; 262 return last_but; 263 } 264 265 Cursor deadmouse = { 266 { 0, 0}, /* offset */ 267 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 268 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41, 269 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0, 270 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 271 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 272 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41, 273 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0, 274 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } 275 }; 276 277 Cursor blot ={ 278 { 0, 0 }, 279 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 280 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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 }; 288 289 Cursor skull ={ 290 { 0, 0 }, 291 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 292 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0, 293 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27, 294 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 295 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 296 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0, 297 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27, 298 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } 299 }; 300 301 confirm(int but) /* ask for confirmation if menu item ends with '?' */ 302 { 303 int c; 304 static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 }; 305 306 esetcursor(&skull); 307 c = waitdown(); 308 waitup(); 309 esetcursor(0); 310 return but == but_cvt[c]; 311 } 312