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
mapscreen(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
clearscreen(void)30 clearscreen(void)
31 {
32 draw(screen, screen->r, display->black, nil, ZP);
33 }
34
35 void
screenprint(char * fmt,...)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 *
getcmdstr(void)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 *
getkbdstr(int c0)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
buttondown(void)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
waitdown(void)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
waitup(void)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
pan(void)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 getmousestr(void)
197 {
198 static char buf[64];
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 snprint(buf, sizeof buf, "m%g", mag * 1.1);
218 return buf;
219 case Smaller:
220 snprint(buf, sizeof 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
checkmouse(void)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
confirm(int but)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