Blob


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"
9 static int checkmouse(void);
10 /* static int buttondown(void); */
11 static char *getmousestr(void);
12 static char *getkbdstr(int);
14 extern Cursor blot;
15 extern char *track;
17 Mouse mouse;
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 }
29 void
30 clearscreen(void)
31 {
32 draw(screen, screen->r, display->black, nil, ZP);
33 }
35 void
36 screenprint(char *fmt, ...)
37 {
38 char buf[100];
39 Point p;
40 va_list args;
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 }
49 #define Viewkey 0xb2
50 #define etimer(x, y) 0
52 char *
53 getcmdstr(void)
54 {
55 Event ev;
56 int e;
57 static ulong timekey = 0;
58 ulong tracktm = 0;
59 Dir *dir;
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 return nil;
92 }
94 static char *
95 getkbdstr(int c0)
96 {
97 static char buf[100];
98 char *p;
99 int c;
101 if (c0 == '\n')
102 return "";
103 buf[0] = c0;
104 buf[1] = 0;
105 screenprint("%s", buf);
106 for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) {
107 if (c == '\b' && p > buf) {
108 *--p = ' ';
109 } else {
110 *p++ = c;
111 *p = 0;
113 screenprint("%s", buf);
115 *p = 0;
116 return buf;
120 #define button3(b) ((b) & 4)
121 #define button2(b) ((b) & 2)
122 #define button1(b) ((b) & 1)
123 #define button23(b) ((b) & 6)
124 #define button123(b) ((b) & 7)
126 #define butcvt(b) (1 << ((b) - 1))
128 #if 0
129 static int buttondown(void) /* report state of buttons, if any */
131 if (!ecanmouse()) /* no event pending */
132 return 0;
133 mouse = emouse(); /* something, but it could be motion */
134 return mouse.buttons & 7;
136 #endif
138 int waitdown(void) /* wait until some button is down */
140 while (!(mouse.buttons & 7))
141 mouse = emouse();
142 return mouse.buttons & 7;
145 int waitup(void)
147 while (mouse.buttons & 7)
148 mouse = emouse();
149 return mouse.buttons & 7;
152 char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 };
153 char *m2[] = { 0 };
155 enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit };
157 Menu mbut3 = { m3, 0, 0 };
158 Menu mbut2 = { m2, 0, 0 };
160 int last_hit;
161 int last_but;
163 char *pan(void)
165 Point dd, xy, lastxy, min, max;
167 esetcursor(&blot);
168 waitdown();
169 xy = mouse.xy;
170 do{
171 lastxy = mouse.xy;
172 mouse = emouse();
173 dd = subpt(mouse.xy, lastxy);
174 min = addpt(screen->clipr.min, dd);
175 max = addpt(screen->clipr.max, dd);
176 draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)),
177 screen, nil, screen->r.min);
178 if(mouse.xy.x < lastxy.x) /* moved left, clear right */
179 draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y),
180 display->white, nil, ZP);
181 else /* moved right, clear left*/
182 draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y),
183 display->white, nil, ZP);
184 if(mouse.xy.y < lastxy.y) /* moved up, clear down */
185 draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y),
186 display->white, nil, ZP);
187 else /* moved down, clear up */
188 draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y),
189 display->white, nil, ZP);
190 flushimage(display, 1);
191 }while(mouse.buttons);
193 xyoffset = addpt(xyoffset, subpt(mouse.xy, xy));
195 esetcursor(0);
196 return "p";
199 static char *getmousestr(void)
201 static char buf[20];
203 checkmouse();
204 if (last_but == 1)
205 return "p"; /* repaint after panning */
206 if (last_but == 2) {
207 return "c";
208 } else if (last_but == 3) {
209 switch (last_hit) {
210 case Next:
211 return "";
212 case Prev:
213 return "-1";
214 case Page:
215 screenprint("page? ");
216 return "c";
217 case Again:
218 return "p";
219 case Bigger:
220 sprint(buf, "m%g", mag * 1.1);
221 return buf;
222 case Smaller:
223 sprint(buf, "m%g", mag / 1.1);
224 return buf;
225 case Pan:
226 return pan();
227 case Quit:
228 return "q";
229 default:
230 return "c";
232 } else { /* button 1 or bail out */
233 return "c";
237 static int
238 checkmouse(void) /* return button touched if any */
240 int c, b;
241 char *p;
242 extern int confirm(int);
244 b = waitdown();
245 last_but = 0;
246 last_hit = -1;
247 c = 0;
248 if (button3(b)) {
249 last_hit = emenuhit(3, &mouse, &mbut3);
250 last_but = 3;
251 } else if (button2(b)) {
252 last_hit = emenuhit(2, &mouse, &mbut2);
253 last_but = 2;
254 } else { /* button1() */
255 pan();
256 last_but = 1;
258 waitup();
259 if (last_but == 3 && last_hit >= 0) {
260 p = m3[last_hit];
261 c = p[strlen(p) - 1];
263 if (c == '?' && !confirm(last_but))
264 last_hit = -1;
265 return last_but;
268 Cursor deadmouse = {
269 { 0, 0}, /* offset */
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 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
276 0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
277 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
278 };
280 Cursor blot ={
281 { 0, 0 },
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 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
290 };
292 Cursor skull ={
293 { 0, 0 },
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 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
299 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
300 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
301 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
302 };
304 int
305 confirm(int but) /* ask for confirmation if menu item ends with '?' */
307 int c;
308 static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 };
310 esetcursor(&skull);
311 c = waitdown();
312 waitup();
313 esetcursor(0);
314 return but == but_cvt[c];