tgetrect.c - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tgetrect.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 }