From ed7c8e8d02c02bdbff1e88a6d8d1419f39af48ad Mon Sep 17 00:00:00 2001 From: rsc Date: Tue, 30 Sep 2003 17:47:42 +0000 Subject: Initial import. --- src/libdraw/getrect.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/libdraw/getrect.c (limited to 'src/libdraw/getrect.c') diff --git a/src/libdraw/getrect.c b/src/libdraw/getrect.c new file mode 100644 index 00000000..a050e4c4 --- /dev/null +++ b/src/libdraw/getrect.c @@ -0,0 +1,133 @@ +#include +#include +#include +#include +#include +#include + +#define W Borderwidth + +static Image *tmp[4]; +static Image *red; + +static Cursor sweep={ + {-7, -7}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, + 0xE0, 0x07, 0xE0, 0x07, 0xE3, 0xF7, 0xE3, 0xF7, + 0xE3, 0xE7, 0xE3, 0xF7, 0xE3, 0xFF, 0xE3, 0x7F, + 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,}, + {0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02, + 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x41, 0xE2, + 0x41, 0xC2, 0x41, 0xE2, 0x41, 0x72, 0x40, 0x38, + 0x40, 0x1C, 0x40, 0x0E, 0x7F, 0xE6, 0x00, 0x00,} +}; + +static +void +brects(Rectangle r, Rectangle rp[4]) +{ + if(Dx(r) < 2*W) + r.max.x = r.min.x+2*W; + if(Dy(r) < 2*W) + r.max.y = r.min.y+2*W; + rp[0] = Rect(r.min.x, r.min.y, r.max.x, r.min.y+W); + rp[1] = Rect(r.min.x, r.max.y-W, r.max.x, r.max.y); + rp[2] = Rect(r.min.x, r.min.y+W, r.min.x+W, r.max.y-W); + rp[3] = Rect(r.max.x-W, r.min.y+W, r.max.x, r.max.y-W); +} + +Rectangle +getrect(int but, Mousectl *mc) +{ + Rectangle r, rc; + + but = 1<<(but-1); + setcursor(mc, &sweep); + while(mc->m.buttons) + readmouse(mc); + while(!(mc->m.buttons & but)){ + readmouse(mc); + if(mc->m.buttons & (7^but)) + goto Return; + } + r.min = mc->m.xy; + r.max = mc->m.xy; + do{ + rc = canonrect(r); + drawgetrect(rc, 1); + readmouse(mc); + drawgetrect(rc, 0); + r.max = mc->m.xy; + }while(mc->m.buttons == but); + + Return: + setcursor(mc, nil); + if(mc->m.buttons & (7^but)){ + rc.min.x = rc.max.x = 0; + rc.min.y = rc.max.y = 0; + while(mc->m.buttons) + readmouse(mc); + } + return rc; +} + +static +void +freetmp(void) +{ + freeimage(tmp[0]); + freeimage(tmp[1]); + freeimage(tmp[2]); + freeimage(tmp[3]); + freeimage(red); + tmp[0] = tmp[1] = tmp[2] = tmp[3] = red = nil; +} + +static +int +max(int a, int b) +{ + if(a > b) + return a; + return b; +} + +void +drawgetrect(Rectangle rc, int up) +{ + int i; + Rectangle r, rects[4]; + + /* + * BUG: if for some reason we have two of these going on at once + * when we must grow the tmp buffers, we lose data. Also if tmp + * is unallocated and we ask to restore the screen, it would be nice + * to complain, but we silently make a mess. + */ + if(up && tmp[0]!=nil) + if(Dx(tmp[0]->r)r)screenimage->r), Dx(rc)), W); + tmp[0] = allocimage(display, r, screen->chan, 0, -1); + tmp[1] = allocimage(display, r, screen->chan, 0, -1); + r = Rect(0, 0, W, max(Dy(display->screenimage->r), Dy(rc))); + tmp[2] = allocimage(display, r, screen->chan, 0, -1); + tmp[3] = allocimage(display, r, screen->chan, 0, -1); + red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed); + if(tmp[0]==0 || tmp[1]==0 || tmp[2]==0 || tmp[3]==0 || red==0){ + freetmp(); + drawerror(display, "getrect: allocimage failed"); + } + } + brects(rc, rects); + if(!up){ + for(i=0; i<4; i++) + draw(screen, rects[i], tmp[i], nil, ZP); + return; + } + for(i=0; i<4; i++){ + draw(tmp[i], Rect(0, 0, Dx(rects[i]), Dy(rects[i])), screen, nil, rects[i].min); + draw(screen, rects[i], red, nil, ZP); + } +} -- cgit v1.2.3