Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}