17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <cursor.h>
67dd7cddfSDavid du Colombier #include <mouse.h>
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier #define W Borderwidth
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier static Image *tmp[4];
117dd7cddfSDavid du Colombier static Image *red;
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier static Cursor sweep={
147dd7cddfSDavid du Colombier {-7, -7},
157dd7cddfSDavid du Colombier {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07,
167dd7cddfSDavid du Colombier 0xE0, 0x07, 0xE0, 0x07, 0xE3, 0xF7, 0xE3, 0xF7,
177dd7cddfSDavid du Colombier 0xE3, 0xE7, 0xE3, 0xF7, 0xE3, 0xFF, 0xE3, 0x7F,
187dd7cddfSDavid du Colombier 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,},
197dd7cddfSDavid du Colombier {0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02,
207dd7cddfSDavid du Colombier 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x41, 0xE2,
217dd7cddfSDavid du Colombier 0x41, 0xC2, 0x41, 0xE2, 0x41, 0x72, 0x40, 0x38,
227dd7cddfSDavid du Colombier 0x40, 0x1C, 0x40, 0x0E, 0x7F, 0xE6, 0x00, 0x00,}
237dd7cddfSDavid du Colombier };
247dd7cddfSDavid du Colombier
257dd7cddfSDavid du Colombier static
267dd7cddfSDavid du Colombier void
brects(Rectangle r,Rectangle rp[4])277dd7cddfSDavid du Colombier brects(Rectangle r, Rectangle rp[4])
287dd7cddfSDavid du Colombier {
297dd7cddfSDavid du Colombier if(Dx(r) < 2*W)
307dd7cddfSDavid du Colombier r.max.x = r.min.x+2*W;
317dd7cddfSDavid du Colombier if(Dy(r) < 2*W)
327dd7cddfSDavid du Colombier r.max.y = r.min.y+2*W;
337dd7cddfSDavid du Colombier rp[0] = Rect(r.min.x, r.min.y, r.max.x, r.min.y+W);
347dd7cddfSDavid du Colombier rp[1] = Rect(r.min.x, r.max.y-W, r.max.x, r.max.y);
357dd7cddfSDavid du Colombier rp[2] = Rect(r.min.x, r.min.y+W, r.min.x+W, r.max.y-W);
367dd7cddfSDavid du Colombier rp[3] = Rect(r.max.x-W, r.min.y+W, r.max.x, r.max.y-W);
377dd7cddfSDavid du Colombier }
387dd7cddfSDavid du Colombier
397dd7cddfSDavid du Colombier Rectangle
getrect(int but,Mousectl * mc)407dd7cddfSDavid du Colombier getrect(int but, Mousectl *mc)
417dd7cddfSDavid du Colombier {
427dd7cddfSDavid du Colombier Rectangle r, rc;
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier but = 1<<(but-1);
457dd7cddfSDavid du Colombier setcursor(mc, &sweep);
467dd7cddfSDavid du Colombier while(mc->buttons)
477dd7cddfSDavid du Colombier readmouse(mc);
487dd7cddfSDavid du Colombier while(!(mc->buttons & but)){
497dd7cddfSDavid du Colombier readmouse(mc);
507dd7cddfSDavid du Colombier if(mc->buttons & (7^but))
517dd7cddfSDavid du Colombier goto Return;
527dd7cddfSDavid du Colombier }
537dd7cddfSDavid du Colombier r.min = mc->xy;
547dd7cddfSDavid du Colombier r.max = mc->xy;
557dd7cddfSDavid du Colombier do{
567dd7cddfSDavid du Colombier rc = canonrect(r);
577dd7cddfSDavid du Colombier drawgetrect(rc, 1);
587dd7cddfSDavid du Colombier readmouse(mc);
597dd7cddfSDavid du Colombier drawgetrect(rc, 0);
607dd7cddfSDavid du Colombier r.max = mc->xy;
617dd7cddfSDavid du Colombier }while(mc->buttons == but);
627dd7cddfSDavid du Colombier
637dd7cddfSDavid du Colombier Return:
647dd7cddfSDavid du Colombier setcursor(mc, nil);
657dd7cddfSDavid du Colombier if(mc->buttons & (7^but)){
667dd7cddfSDavid du Colombier rc.min.x = rc.max.x = 0;
677dd7cddfSDavid du Colombier rc.min.y = rc.max.y = 0;
687dd7cddfSDavid du Colombier while(mc->buttons)
697dd7cddfSDavid du Colombier readmouse(mc);
707dd7cddfSDavid du Colombier }
717dd7cddfSDavid du Colombier return rc;
727dd7cddfSDavid du Colombier }
737dd7cddfSDavid du Colombier
747dd7cddfSDavid du Colombier static
757dd7cddfSDavid du Colombier void
freetmp(void)767dd7cddfSDavid du Colombier freetmp(void)
777dd7cddfSDavid du Colombier {
787dd7cddfSDavid du Colombier freeimage(tmp[0]);
797dd7cddfSDavid du Colombier freeimage(tmp[1]);
807dd7cddfSDavid du Colombier freeimage(tmp[2]);
817dd7cddfSDavid du Colombier freeimage(tmp[3]);
827dd7cddfSDavid du Colombier freeimage(red);
837dd7cddfSDavid du Colombier tmp[0] = tmp[1] = tmp[2] = tmp[3] = red = nil;
847dd7cddfSDavid du Colombier }
857dd7cddfSDavid du Colombier
867dd7cddfSDavid du Colombier static
877dd7cddfSDavid du Colombier int
max(int a,int b)887dd7cddfSDavid du Colombier max(int a, int b)
897dd7cddfSDavid du Colombier {
907dd7cddfSDavid du Colombier if(a > b)
917dd7cddfSDavid du Colombier return a;
927dd7cddfSDavid du Colombier return b;
937dd7cddfSDavid du Colombier }
947dd7cddfSDavid du Colombier
957dd7cddfSDavid du Colombier void
drawgetrect(Rectangle rc,int up)967dd7cddfSDavid du Colombier drawgetrect(Rectangle rc, int up)
977dd7cddfSDavid du Colombier {
987dd7cddfSDavid du Colombier int i;
997dd7cddfSDavid du Colombier Rectangle r, rects[4];
1007dd7cddfSDavid du Colombier
1017dd7cddfSDavid du Colombier /*
1027dd7cddfSDavid du Colombier * BUG: if for some reason we have two of these going on at once
1037dd7cddfSDavid du Colombier * when we must grow the tmp buffers, we lose data. Also if tmp
1047dd7cddfSDavid du Colombier * is unallocated and we ask to restore the screen, it would be nice
1057dd7cddfSDavid du Colombier * to complain, but we silently make a mess.
1067dd7cddfSDavid du Colombier */
1077dd7cddfSDavid du Colombier if(up && tmp[0]!=nil)
10859cc4ca5SDavid du Colombier if(Dx(tmp[0]->r)<Dx(rc) || Dy(tmp[2]->r)<Dy(rc))
1097dd7cddfSDavid du Colombier freetmp();
1107dd7cddfSDavid du Colombier if(tmp[0] == 0){
111*9a747e4fSDavid du Colombier r = Rect(0, 0, max(Dx(display->screenimage->r), Dx(rc)), W);
112*9a747e4fSDavid du Colombier tmp[0] = allocimage(display, r, screen->chan, 0, -1);
113*9a747e4fSDavid du Colombier tmp[1] = allocimage(display, r, screen->chan, 0, -1);
114*9a747e4fSDavid du Colombier r = Rect(0, 0, W, max(Dy(display->screenimage->r), Dy(rc)));
115*9a747e4fSDavid du Colombier tmp[2] = allocimage(display, r, screen->chan, 0, -1);
116*9a747e4fSDavid du Colombier tmp[3] = allocimage(display, r, screen->chan, 0, -1);
117*9a747e4fSDavid du Colombier red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
1187dd7cddfSDavid du Colombier if(tmp[0]==0 || tmp[1]==0 || tmp[2]==0 || tmp[3]==0 || red==0){
1197dd7cddfSDavid du Colombier freetmp();
1207dd7cddfSDavid du Colombier drawerror(display, "getrect: allocimage failed");
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier }
1237dd7cddfSDavid du Colombier brects(rc, rects);
1247dd7cddfSDavid du Colombier if(!up){
1257dd7cddfSDavid du Colombier for(i=0; i<4; i++)
1267dd7cddfSDavid du Colombier draw(screen, rects[i], tmp[i], nil, ZP);
1277dd7cddfSDavid du Colombier return;
1287dd7cddfSDavid du Colombier }
1297dd7cddfSDavid du Colombier for(i=0; i<4; i++){
1307dd7cddfSDavid du Colombier draw(tmp[i], Rect(0, 0, Dx(rects[i]), Dy(rects[i])), screen, nil, rects[i].min);
1317dd7cddfSDavid du Colombier draw(screen, rects[i], red, nil, ZP);
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier }
134