]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libdraw/egetrect.c
fltfmt: %.0g should print with one significant figure
[plan9front.git] / sys / src / libdraw / egetrect.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <cursor.h>
5 #include <event.h>
6
7 #define W       Borderwidth
8
9 static Image *tmp[4];
10 static Image *red;
11
12 static Cursor sweep={
13         {-7, -7},
14         {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07,
15          0xE0, 0x07, 0xE0, 0x07, 0xE3, 0xF7, 0xE3, 0xF7,
16          0xE3, 0xE7, 0xE3, 0xF7, 0xE3, 0xFF, 0xE3, 0x7F,
17          0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,},
18         {0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02,
19          0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x41, 0xE2,
20          0x41, 0xC2, 0x41, 0xE2, 0x41, 0x72, 0x40, 0x38,
21          0x40, 0x1C, 0x40, 0x0E, 0x7F, 0xE6, 0x00, 0x00,}
22 };
23
24 static
25 void
26 brects(Rectangle r, Rectangle rp[4])
27 {
28         if(Dx(r) < 2*W)
29                 r.max.x = r.min.x+2*W;
30         if(Dy(r) < 2*W)
31                 r.max.y = r.min.y+2*W;
32         rp[0] = Rect(r.min.x, r.min.y, r.max.x, r.min.y+W);
33         rp[1] = Rect(r.min.x, r.max.y-W, r.max.x, r.max.y);
34         rp[2] = Rect(r.min.x, r.min.y+W, r.min.x+W, r.max.y-W);
35         rp[3] = Rect(r.max.x-W, r.min.y+W, r.max.x, r.max.y-W);
36 }
37
38 Rectangle
39 egetrect(int but, Mouse *m)
40 {
41         Rectangle r, rc;
42
43         but = 1<<(but-1);
44         esetcursor(&sweep);
45         while(m->buttons)
46                 *m = emouse();
47         while(!(m->buttons & but)){
48                 *m = emouse();
49                 if(m->buttons & (7^but))
50                         goto Return;
51         }
52         r.min = m->xy;
53         r.max = m->xy;
54         do{
55                 rc = canonrect(r);
56                 edrawgetrect(rc, 1);
57                 *m = emouse();
58                 edrawgetrect(rc, 0);
59                 r.max = m->xy;
60         }while(m->buttons == but);
61
62     Return:
63         esetcursor(0);
64         if(m->buttons & (7^but)){
65                 rc.min.x = rc.max.x = 0;
66                 rc.min.y = rc.max.y = 0;
67                 while(m->buttons)
68                         *m = emouse();
69         }
70         return rc;
71 }
72
73 static
74 void
75 freetmp(void)
76 {
77         freeimage(tmp[0]);
78         freeimage(tmp[1]);
79         freeimage(tmp[2]);
80         freeimage(tmp[3]);
81         freeimage(red);
82         tmp[0] = tmp[1] = tmp[2] = tmp[3] = red = nil;
83 }
84
85 void
86 edrawgetrect(Rectangle rc, int up)
87 {
88         int i;
89         Rectangle r, rects[4];
90
91         if(up && tmp[0]!=nil)
92                 if(Dx(tmp[0]->r)<Dx(rc) || Dy(tmp[2]->r)<Dy(rc))
93                         freetmp();
94
95         if(tmp[0] == 0){
96                 r = Rect(0, 0, Dx(screen->r), W);
97                 tmp[0] = allocimage(display, r, screen->chan, 0, -1);
98                 tmp[1] = allocimage(display, r, screen->chan, 0, -1);
99                 r = Rect(0, 0, W, Dy(screen->r));
100                 tmp[2] = allocimage(display, r, screen->chan, 0, -1);
101                 tmp[3] = allocimage(display, r, screen->chan, 0, -1);
102                 red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
103                 if(tmp[0]==0 || tmp[1]==0 || tmp[2]==0 || tmp[3]==0 || red==0)
104                         drawerror(display, "getrect: allocimage failed");
105         }
106         brects(rc, rects);
107         if(!up){
108                 for(i=0; i<4; i++)
109                         draw(screen, rects[i], tmp[i], nil, ZP);
110                 return;
111         }
112         for(i=0; i<4; i++){
113                 draw(tmp[i], Rect(0, 0, Dx(rects[i]), Dy(rects[i])), screen, nil, rects[i].min);
114                 draw(screen, rects[i], red, nil, ZP);
115         }
116 }