getrect.c (3064B)
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->m.buttons) 47 readmouse(mc); 48 while(!(mc->m.buttons & but)){ 49 readmouse(mc); 50 if(mc->m.buttons & (7^but)) 51 goto Return; 52 } 53 r.min = mc->m.xy; 54 r.max = mc->m.xy; 55 do{ 56 rc = canonrect(r); 57 drawgetrect(rc, 1); 58 readmouse(mc); 59 drawgetrect(rc, 0); 60 r.max = mc->m.xy; 61 }while(mc->m.buttons == but); 62 63 Return: 64 setcursor(mc, nil); 65 if(mc->m.buttons & (7^but)){ 66 rc.min.x = rc.max.x = 0; 67 rc.min.y = rc.max.y = 0; 68 while(mc->m.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 }