1 #include <u.h> 2 #include <libg.h> 3 #include <libc.h> 4 #include <stdarg.h> 5 #include <bio.h> 6 #include "proof.h" 7 8 Bitmap screen; 9 Mouse mouse; 10 11 static int checkmouse(void); 12 static int buttondown(void); 13 static char *getmousestr(void); 14 static char *getkbdstr(int); 15 16 extern Cursor blot; 17 extern char *track; 18 19 void 20 mapscreen(void) 21 { 22 binit(0, 0, "proof"); 23 einit(Ekeyboard|Emouse); 24 } 25 26 void 27 clearscreen(void) 28 { 29 bitblt(&screen, screen.r.min, &screen, screen.r, 0); 30 } 31 32 void 33 screenprint(char *fmt, ...) 34 { 35 char buf[100]; 36 Point p; 37 va_list args; 38 39 va_start(args, fmt); 40 doprint(buf, &buf[sizeof buf], fmt, args); 41 va_end(args); 42 p = Pt(screen.clipr.min.x+40, screen.clipr.max.y-40); 43 string(&screen, p, font, buf, S); 44 } 45 46 47 #define Viewkey 0xb2 48 49 char * 50 getcmdstr(void) 51 { 52 Event ev; 53 int e; 54 static ulong timekey = 0; 55 ulong tracktm = 0; 56 Dir dir; 57 58 if(track){ 59 if(timekey == 0) 60 timekey = etimer(0, 5000); 61 if(dirstat(track, &dir) >= 0) 62 tracktm = dir.mtime; 63 } 64 for (;;) { 65 e = event(&ev); 66 if ((e & Emouse) && ev.mouse.buttons) { 67 mouse = ev.mouse; 68 return getmousestr(); 69 } else if (e & Ekeyboard) 70 return getkbdstr(ev.kbdc); /* sadly, no way to unget */ 71 else if (e & timekey) { 72 if((dirstat(track, &dir) >= 0) && (tracktm < dir.mtime)) 73 return "q\n"; 74 } 75 } 76 } 77 78 char * 79 getkbdstr(int c0) 80 { 81 static char buf[100]; 82 char *p; 83 int c; 84 85 if (c0 == '\n') 86 return ""; 87 buf[0] = c0; 88 buf[1] = 0; 89 screenprint("%s", buf); 90 for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) { 91 if (c == '\b' && p > buf) { 92 *--p = ' '; 93 } else { 94 *p++ = c; 95 *p = 0; 96 } 97 screenprint("%s", buf); 98 } 99 *p = 0; 100 return buf; 101 } 102 103 104 #define button3(b) ((b) & 4) 105 #define button2(b) ((b) & 2) 106 #define button1(b) ((b) & 1) 107 #define button23(b) ((b) & 6) 108 #define button123(b) ((b) & 7) 109 110 #define butcvt(b) (1 << ((b) - 1)) 111 112 int buttondown(void) /* report state of buttons, if any */ 113 { 114 if (!ecanmouse()) /* no event pending */ 115 return 0; 116 mouse = emouse(); /* something, but it could be motion */ 117 return mouse.buttons & 7; 118 } 119 120 int waitdown(void) /* wait until some button is down */ 121 { 122 while (!(mouse.buttons & 7)) 123 mouse = emouse(); 124 return mouse.buttons & 7; 125 } 126 127 int waitup(void) 128 { 129 while (mouse.buttons & 7) 130 mouse = emouse(); 131 return mouse.buttons & 7; 132 } 133 134 char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 }; 135 char *m2[] = { 0 }; 136 137 enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit }; 138 139 Menu mbut3 = { m3, 0, 0 }; 140 Menu mbut2 = { m2, 0, 0 }; 141 142 int last_hit; 143 int last_but; 144 145 char *pan(void) 146 { 147 Point dd, xy, lastxy, min, max; 148 149 cursorswitch(&blot); 150 waitdown(); 151 xy = mouse.xy; 152 do{ 153 lastxy = mouse.xy; 154 mouse = emouse(); 155 dd = sub(mouse.xy, lastxy); 156 min = add(screen.clipr.min, dd); 157 max = add(screen.clipr.max, dd); 158 bitblt(&screen, add(screen.r.min, sub(mouse.xy, lastxy)), &screen, screen.r, S); 159 if(mouse.xy.x < lastxy.x) /* moved left, clear right */ 160 bitblt(&screen, Pt(max.x, screen.r.min.y), &screen, 161 Rect(max.x, screen.r.min.y, screen.r.max.x, screen.r.max.y), 0); 162 else /* moved right, clear left*/ 163 bitblt(&screen, screen.r.min, &screen, 164 Rect(screen.r.min.x, screen.r.min.y, min.x, screen.r.max.y), 0); 165 if(mouse.xy.y < lastxy.y) /* moved up, clear down */ 166 bitblt(&screen, Pt(screen.r.min.x, max.y), &screen, 167 Rect(screen.r.min.x, max.y, screen.r.max.x, screen.r.max.y), 0); 168 else /* moved down, clear up */ 169 bitblt(&screen, screen.r.min, &screen, 170 Rect(screen.r.min.x, screen.r.min.y, screen.r.max.x, min.y), 0); 171 bflush(); 172 }while(mouse.buttons); 173 174 xyoffset = add(xyoffset, sub(mouse.xy, xy)); 175 176 cursorswitch(0); 177 return "p"; 178 } 179 180 char *getmousestr(void) 181 { 182 static char buf[20]; 183 184 checkmouse(); 185 if (last_but == 2) { 186 return "c"; 187 } else if (last_but == 3) { 188 switch (last_hit) { 189 case Next: 190 return ""; 191 case Prev: 192 return "-1"; 193 case Page: 194 screenprint("page? "); 195 return "c"; 196 case Again: 197 return "p"; 198 case Bigger: 199 sprint(buf, "m%g", mag * 1.1); 200 return buf; 201 case Smaller: 202 sprint(buf, "m%g", mag / 1.1); 203 return buf; 204 case Pan: 205 return pan(); 206 case Quit: 207 return "q"; 208 default: 209 return "c"; 210 } 211 } else { /* button 1 or bail out */ 212 return "c"; 213 } 214 } 215 216 int 217 checkmouse(void) /* return button touched if any */ 218 { 219 int c, b; 220 char *p; 221 extern int confirm(int); 222 223 b = waitdown(); 224 last_but = 0; 225 last_hit = -1; 226 c = 0; 227 if (button3(b)) { 228 last_hit = menuhit(3, &mouse, &mbut3); 229 last_but = 3; 230 } else if (button2(b)) { 231 last_hit = menuhit(2, &mouse, &mbut2); 232 last_but = 2; 233 } else { /* button1() */ 234 last_but = 1; 235 } 236 waitup(); 237 if (last_but == 3 && last_hit >= 0) { 238 p = m3[last_hit]; 239 c = p[strlen(p) - 1]; 240 } 241 if (c == '?' && !confirm(last_but)) 242 last_hit = -1; 243 return last_but; 244 } 245 246 Cursor deadmouse = { 247 { 0, 0}, /* offset */ 248 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 249 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41, 250 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0, 251 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 252 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 253 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41, 254 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0, 255 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } 256 }; 257 258 Cursor blot ={ 259 { 0, 0 }, 260 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 261 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 262 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 263 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, 264 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 265 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 266 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 267 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, } 268 }; 269 270 Cursor skull ={ 271 { 0, 0 }, 272 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 273 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0, 274 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27, 275 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 276 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 277 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0, 278 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27, 279 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } 280 }; 281 282 confirm(int but) /* ask for confirmation if menu item ends with '?' */ 283 { 284 int c; 285 static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 }; 286 287 cursorswitch(&skull); 288 c = waitdown(); 289 waitup(); 290 cursorswitch(0); 291 return but == but_cvt[c]; 292 } 293