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 } 91 92 static char * 93 getkbdstr(int c0) 94 { 95 static char buf[100]; 96 char *p; 97 int c; 98 99 if (c0 == '\n') 100 return ""; 101 buf[0] = c0; 102 buf[1] = 0; 103 screenprint("%s", buf); 104 for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) { 105 if (c == '\b' && p > buf) { 106 *--p = ' '; 107 } else { 108 *p++ = c; 109 *p = 0; 110 } 111 screenprint("%s", buf); 112 } 113 *p = 0; 114 return buf; 115 } 116 117 118 #define button3(b) ((b) & 4) 119 #define button2(b) ((b) & 2) 120 #define button1(b) ((b) & 1) 121 #define button23(b) ((b) & 6) 122 #define button123(b) ((b) & 7) 123 124 #define butcvt(b) (1 << ((b) - 1)) 125 126 static int buttondown(void) /* report state of buttons, if any */ 127 { 128 if (!ecanmouse()) /* no event pending */ 129 return 0; 130 mouse = emouse(); /* something, but it could be motion */ 131 return mouse.buttons & 7; 132 } 133 134 int waitdown(void) /* wait until some button is down */ 135 { 136 while (!(mouse.buttons & 7)) 137 mouse = emouse(); 138 return mouse.buttons & 7; 139 } 140 141 int waitup(void) 142 { 143 while (mouse.buttons & 7) 144 mouse = emouse(); 145 return mouse.buttons & 7; 146 } 147 148 char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 }; 149 char *m2[] = { 0 }; 150 151 enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit }; 152 153 Menu mbut3 = { m3, 0, 0 }; 154 Menu mbut2 = { m2, 0, 0 }; 155 156 int last_hit; 157 int last_but; 158 159 char *pan(void) 160 { 161 Point dd, xy, lastxy, min, max; 162 163 esetcursor(&blot); 164 waitdown(); 165 xy = mouse.xy; 166 do{ 167 lastxy = mouse.xy; 168 mouse = emouse(); 169 dd = subpt(mouse.xy, lastxy); 170 min = addpt(screen->clipr.min, dd); 171 max = addpt(screen->clipr.max, dd); 172 draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)), 173 screen, nil, screen->r.min); 174 if(mouse.xy.x < lastxy.x) /* moved left, clear right */ 175 draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y), 176 display->white, nil, ZP); 177 else /* moved right, clear left*/ 178 draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y), 179 display->white, nil, ZP); 180 if(mouse.xy.y < lastxy.y) /* moved up, clear down */ 181 draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y), 182 display->white, nil, ZP); 183 else /* moved down, clear up */ 184 draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y), 185 display->white, nil, ZP); 186 flushimage(display, 1); 187 }while(mouse.buttons); 188 189 xyoffset = addpt(xyoffset, subpt(mouse.xy, xy)); 190 191 esetcursor(0); 192 return "p"; 193 } 194 195 static char *getmousestr(void) 196 { 197 static char buf[20]; 198 199 checkmouse(); 200 if (last_but == 1) 201 return "p"; /* repaint after panning */ 202 if (last_but == 2) { 203 return "c"; 204 } else if (last_but == 3) { 205 switch (last_hit) { 206 case Next: 207 return ""; 208 case Prev: 209 return "-1"; 210 case Page: 211 screenprint("page? "); 212 return "c"; 213 case Again: 214 return "p"; 215 case Bigger: 216 sprint(buf, "m%g", mag * 1.1); 217 return buf; 218 case Smaller: 219 sprint(buf, "m%g", mag / 1.1); 220 return buf; 221 case Pan: 222 return pan(); 223 case Quit: 224 return "q"; 225 default: 226 return "c"; 227 } 228 } else { /* button 1 or bail out */ 229 return "c"; 230 } 231 } 232 233 static int 234 checkmouse(void) /* return button touched if any */ 235 { 236 int c, b; 237 char *p; 238 extern int confirm(int); 239 240 b = waitdown(); 241 last_but = 0; 242 last_hit = -1; 243 c = 0; 244 if (button3(b)) { 245 last_hit = emenuhit(3, &mouse, &mbut3); 246 last_but = 3; 247 } else if (button2(b)) { 248 last_hit = emenuhit(2, &mouse, &mbut2); 249 last_but = 2; 250 } else { /* button1() */ 251 pan(); 252 last_but = 1; 253 } 254 waitup(); 255 if (last_but == 3 && last_hit >= 0) { 256 p = m3[last_hit]; 257 c = p[strlen(p) - 1]; 258 } 259 if (c == '?' && !confirm(last_but)) 260 last_hit = -1; 261 return last_but; 262 } 263 264 Cursor deadmouse = { 265 { 0, 0}, /* offset */ 266 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 267 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41, 268 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0, 269 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 270 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 271 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41, 272 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0, 273 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } 274 }; 275 276 Cursor blot ={ 277 { 0, 0 }, 278 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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 }; 287 288 Cursor skull ={ 289 { 0, 0 }, 290 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 291 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0, 292 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27, 293 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 294 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 295 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0, 296 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27, 297 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } 298 }; 299 300 confirm(int but) /* ask for confirmation if menu item ends with '?' */ 301 { 302 int c; 303 static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 }; 304 305 esetcursor(&skull); 306 c = waitdown(); 307 waitup(); 308 esetcursor(0); 309 return but == but_cvt[c]; 310 } 311