/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <cursor.h>#include <mouse.h> #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,}}; staticvoidbrects(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);} Rectanglegetrect(int but, Mousectl *mc){ Rectangle r, rc; but = 1<<(but-1); setcursor(mc, &sweep); while(mc->buttons) readmouse(mc); while(!(mc->buttons & but)){ readmouse(mc); if(mc->buttons & (7^but)) goto Return; } r.min = mc->xy; r.max = mc->xy; do{ rc = canonrect(r); drawgetrect(rc, 1); readmouse(mc); drawgetrect(rc, 0); r.max = mc->xy; }while(mc->buttons == but); Return: setcursor(mc, nil); if(mc->buttons & (7^but)){ rc.min.x = rc.max.x = 0; rc.min.y = rc.max.y = 0; while(mc->buttons) readmouse(mc); } return rc;} staticvoidfreetmp(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;} staticintmax(int a, int b){ if(a > b) return a; return b;} voiddrawgetrect(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)<Dx(rc) || Dy(tmp[2]->r)<Dy(rc)) freetmp(); if(tmp[0] == 0){ r = Rect(0, 0, max(Dx(display->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); }}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#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->buttons)
readmouse(mc);
while(!(mc->buttons & but)){
readmouse(mc);
if(mc->buttons & (7^but))
goto Return;
}
r.min = mc->xy;
r.max = mc->xy;
do{
rc = canonrect(r);
drawgetrect(rc, 1);
readmouse(mc);
drawgetrect(rc, 0);
r.max = mc->xy;
}while(mc->buttons == but);
Return:
setcursor(mc, nil);
if(mc->buttons & (7^but)){
rc.min.x = rc.max.x = 0;
rc.min.y = rc.max.y = 0;
while(mc->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)<Dx(rc) || Dy(tmp[2]->r)<Dy(rc))
freetmp();
if(tmp[0] == 0){
r = Rect(0, 0, max(Dx(display->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);
}
}