Subversion Repositories planix.SVN

Rev

Details | 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 <thread.h>
5
#include <cursor.h>
6
#include <mouse.h>
7
 
8
#define	W	Borderwidth
9
 
10
static Image *tmp[4];
11
static Image *red;
12
 
13
static Cursor sweep={
14
	{-7, -7},
15
	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07,
16
	 0xE0, 0x07, 0xE0, 0x07, 0xE3, 0xF7, 0xE3, 0xF7,
17
	 0xE3, 0xE7, 0xE3, 0xF7, 0xE3, 0xFF, 0xE3, 0x7F,
18
	 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,},
19
	{0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02,
20
	 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x41, 0xE2,
21
	 0x41, 0xC2, 0x41, 0xE2, 0x41, 0x72, 0x40, 0x38,
22
	 0x40, 0x1C, 0x40, 0x0E, 0x7F, 0xE6, 0x00, 0x00,}
23
};
24
 
25
static
26
void
27
brects(Rectangle r, Rectangle rp[4])
28
{
29
	if(Dx(r) < 2*W)
30
		r.max.x = r.min.x+2*W;
31
	if(Dy(r) < 2*W)
32
		r.max.y = r.min.y+2*W;
33
	rp[0] = Rect(r.min.x, r.min.y, r.max.x, r.min.y+W);
34
	rp[1] = Rect(r.min.x, r.max.y-W, r.max.x, r.max.y);
35
	rp[2] = Rect(r.min.x, r.min.y+W, r.min.x+W, r.max.y-W);
36
	rp[3] = Rect(r.max.x-W, r.min.y+W, r.max.x, r.max.y-W);
37
}
38
 
39
Rectangle
40
getrect(int but, Mousectl *mc)
41
{
42
	Rectangle r, rc;
43
 
44
	but = 1<<(but-1);
45
	setcursor(mc, &sweep);
46
	while(mc->buttons)
47
		readmouse(mc);
48
	while(!(mc->buttons & but)){
49
		readmouse(mc);
50
		if(mc->buttons & (7^but))
51
			goto Return;
52
	}
53
	r.min = mc->xy;
54
	r.max = mc->xy;
55
	do{
56
		rc = canonrect(r);
57
		drawgetrect(rc, 1);
58
		readmouse(mc);
59
		drawgetrect(rc, 0);
60
		r.max = mc->xy;
61
	}while(mc->buttons == but);
62
 
63
    Return:
64
	setcursor(mc, nil);
65
	if(mc->buttons & (7^but)){
66
		rc.min.x = rc.max.x = 0;
67
		rc.min.y = rc.max.y = 0;
68
		while(mc->buttons)
69
			readmouse(mc);
70
	}
71
	return rc;
72
}
73
 
74
static
75
void
76
freetmp(void)
77
{
78
	freeimage(tmp[0]);
79
	freeimage(tmp[1]);
80
	freeimage(tmp[2]);
81
	freeimage(tmp[3]);
82
	freeimage(red);
83
	tmp[0] = tmp[1] = tmp[2] = tmp[3] = red = nil;
84
}
85
 
86
static
87
int
88
max(int a, int b)
89
{
90
	if(a > b)
91
		return a;
92
	return b;
93
}
94
 
95
void
96
drawgetrect(Rectangle rc, int up)
97
{
98
	int i;
99
	Rectangle r, rects[4];
100
 
101
	/*
102
	 * BUG: if for some reason we have two of these going on at once
103
	 * when we must grow the tmp buffers, we lose data.  Also if tmp
104
	 * is unallocated and we ask to restore the screen, it would be nice
105
	 * to complain, but we silently make a mess.
106
	 */
107
	if(up && tmp[0]!=nil)
108
		if(Dx(tmp[0]->r)<Dx(rc) || Dy(tmp[2]->r)<Dy(rc))
109
			freetmp();
110
	if(tmp[0] == 0){
111
		r = Rect(0, 0, max(Dx(display->screenimage->r), Dx(rc)), W);
112
		tmp[0] = allocimage(display, r, screen->chan, 0, -1);
113
		tmp[1] = allocimage(display, r, screen->chan, 0, -1);
114
		r = Rect(0, 0, W, max(Dy(display->screenimage->r), Dy(rc)));
115
		tmp[2] = allocimage(display, r, screen->chan, 0, -1);
116
		tmp[3] = allocimage(display, r, screen->chan, 0, -1);
117
		red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
118
		if(tmp[0]==0 || tmp[1]==0 || tmp[2]==0 || tmp[3]==0 || red==0){
119
			freetmp();
120
			drawerror(display, "getrect: allocimage failed");
121
		}
122
	}
123
	brects(rc, rects);
124
	if(!up){
125
		for(i=0; i<4; i++)
126
			draw(screen, rects[i], tmp[i], nil, ZP);
127
		return;
128
	}
129
	for(i=0; i<4; i++){
130
		draw(tmp[i], Rect(0, 0, Dx(rects[i]), Dy(rects[i])), screen, nil, rects[i].min);
131
		draw(screen, rects[i], red, nil, ZP);
132
	}
133
}