]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/proof/screen.c
merge
[plan9front.git] / sys / src / cmd / proof / screen.c
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
51 char *
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 *
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
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
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
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
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 *
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
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
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 }