blob: a9a7ef1fff38c89e0506129ddd53cbff43b5e696 [file] [log] [blame]
rsc020c8052005-01-04 21:24:19 +00001#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
9static int checkmouse(void);
10/* static int buttondown(void); */
11static char *getmousestr(void);
12static char *getkbdstr(int);
13
14extern Cursor blot;
15extern char *track;
16
17Mouse mouse;
18
19void
20mapscreen(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
29void
30clearscreen(void)
31{
32 draw(screen, screen->r, display->black, nil, ZP);
33}
34
35void
36screenprint(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
52char *
53getcmdstr(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 }
rsc020c8052005-01-04 21:24:19 +000091}
92
93static char *
94getkbdstr(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
128static 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
137int waitdown(void) /* wait until some button is down */
138{
139 while (!(mouse.buttons & 7))
140 mouse = emouse();
141 return mouse.buttons & 7;
142}
143
144int waitup(void)
145{
146 while (mouse.buttons & 7)
147 mouse = emouse();
148 return mouse.buttons & 7;
149}
150
151char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 };
152char *m2[] = { 0 };
153
154enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit };
155
156Menu mbut3 = { m3, 0, 0 };
157Menu mbut2 = { m2, 0, 0 };
158
159int last_hit;
160int last_but;
161
162char *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
198static 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
236static int
237checkmouse(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
267Cursor 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
279Cursor 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
291Cursor 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
303int
304confirm(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}