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