URI:
       talloc.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       talloc.c (4188B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 
            5 Image*
            6 allocimage(Display *d, Rectangle r, u32int chan, int repl, u32int val)
            7 {
            8         return _allocimage(nil, d, r, chan, repl, val, 0, 0);
            9 }
           10 
           11 Image*
           12 _allocimage(Image *ai, Display *d, Rectangle r, u32int chan, int repl, u32int val, int screenid, int refresh)
           13 {
           14         uchar *a;
           15         char *err;
           16         Image *i;
           17         Rectangle clipr;
           18         int id;
           19         int depth;
           20 
           21         err = 0;
           22         i = 0;
           23 
           24         if(chan == 0){
           25                 werrstr("bad channel descriptor");
           26                 return nil;
           27         }
           28 
           29         depth = chantodepth(chan);
           30         if(depth == 0){
           31                 err = "bad channel descriptor";
           32     Error:
           33                 if(err)
           34                         werrstr("allocimage: %s", err);
           35                 else
           36                         werrstr("allocimage: %r");
           37                 free(i);
           38                 return 0;
           39         }
           40 
           41         /* flush pending data so we don't get error allocating the image */
           42         flushimage(d, 0);
           43         a = bufimage(d, 1+4+4+1+4+1+4*4+4*4+4);
           44         if(a == 0)
           45                 goto Error;
           46         d->imageid++;
           47         id = d->imageid;
           48         a[0] = 'b';
           49         BPLONG(a+1, id);
           50         BPLONG(a+5, screenid);
           51         a[9] = refresh;
           52         BPLONG(a+10, chan);
           53         a[14] = repl;
           54         BPLONG(a+15, r.min.x);
           55         BPLONG(a+19, r.min.y);
           56         BPLONG(a+23, r.max.x);
           57         BPLONG(a+27, r.max.y);
           58         if(repl)
           59                 /* huge but not infinite, so various offsets will leave it huge, not overflow */
           60                 clipr = Rect(-0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF);
           61         else
           62                 clipr = r;
           63         BPLONG(a+31, clipr.min.x);
           64         BPLONG(a+35, clipr.min.y);
           65         BPLONG(a+39, clipr.max.x);
           66         BPLONG(a+43, clipr.max.y);
           67         BPLONG(a+47, val);
           68         if(flushimage(d, 0) < 0)
           69                 goto Error;
           70 
           71         if(ai)
           72                 i = ai;
           73         else{
           74                 i = malloc(sizeof(Image));
           75                 if(i == nil){
           76                         a = bufimage(d, 1+4);
           77                         if(a){
           78                                 a[0] = 'f';
           79                                 BPLONG(a+1, id);
           80                                 flushimage(d, 0);
           81                         }
           82                         goto Error;
           83                 }
           84         }
           85         i->display = d;
           86         i->id = id;
           87         i->depth = depth;
           88         i->chan = chan;
           89         i->r = r;
           90         i->clipr = clipr;
           91         i->repl = repl;
           92         i->screen = 0;
           93         i->next = 0;
           94         return i;
           95 }
           96 
           97 Image*
           98 namedimage(Display *d, char *name)
           99 {
          100         uchar *a;
          101         char *err, buf[12*12+1];
          102         Image *i;
          103         int id, n;
          104         u32int chan;
          105 
          106         err = 0;
          107         i = 0;
          108 
          109         n = strlen(name);
          110         if(n >= 256){
          111                 err = "name too long";
          112     Error:
          113                 if(err)
          114                         werrstr("namedimage: %s", err);
          115                 else
          116                         werrstr("namedimage: %r");
          117                 if(i)
          118                         free(i);
          119                 return 0;
          120         }
          121         /* flush pending data so we don't get error allocating the image */
          122         flushimage(d, 0);
          123         a = bufimage(d, 1+4+1+n+1);
          124         if(a == 0)
          125                 goto Error;
          126         d->imageid++;
          127         id = d->imageid;
          128         a[0] = 'n';
          129         BPLONG(a+1, id);
          130         a[5] = n;
          131         memmove(a+6, name, n);
          132         a[6+n] = 'I';
          133         if(flushimage(d, 0) < 0)
          134                 goto Error;
          135         if(_displayrddraw(d, buf, sizeof buf) < 12*12)
          136                 goto Error;
          137         buf[12*12] = '\0';
          138 
          139         i = malloc(sizeof(Image));
          140         if(i == nil){
          141         Error1:
          142                 a = bufimage(d, 1+4);
          143                 if(a){
          144                         a[0] = 'f';
          145                         BPLONG(a+1, id);
          146                         flushimage(d, 0);
          147                 }
          148                 goto Error;
          149         }
          150         i->display = d;
          151         i->id = id;
          152         if((chan=strtochan(buf+2*12))==0){
          153                 werrstr("bad channel '%.12s' from devdraw", buf+2*12);
          154                 goto Error1;
          155         }
          156         i->chan = chan;
          157         i->depth = chantodepth(chan);
          158         i->repl = atoi(buf+3*12);
          159         i->r.min.x = atoi(buf+4*12);
          160         i->r.min.y = atoi(buf+5*12);
          161         i->r.max.x = atoi(buf+6*12);
          162         i->r.max.y = atoi(buf+7*12);
          163         i->clipr.min.x = atoi(buf+8*12);
          164         i->clipr.min.y = atoi(buf+9*12);
          165         i->clipr.max.x = atoi(buf+10*12);
          166         i->clipr.max.y = atoi(buf+11*12);
          167         i->screen = 0;
          168         i->next = 0;
          169         return i;
          170 }
          171 
          172 int
          173 nameimage(Image *i, char *name, int in)
          174 {
          175         uchar *a;
          176         int n;
          177 
          178         n = strlen(name);
          179         a = bufimage(i->display, 1+4+1+1+n);
          180         if(a == 0)
          181                 return 0;
          182         a[0] = 'N';
          183         BPLONG(a+1, i->id);
          184         a[5] = in;
          185         a[6] = n;
          186         memmove(a+7, name, n);
          187         if(flushimage(i->display, 0) < 0)
          188                 return 0;
          189         return 1;
          190 }
          191 
          192 int
          193 _freeimage1(Image *i)
          194 {
          195         uchar *a;
          196         Display *d;
          197         Image *w;
          198 
          199         if(i == 0 || i->display == 0)
          200                 return 0;
          201         /* make sure no refresh events occur on this if we block in the write */
          202         d = i->display;
          203         /* flush pending data so we don't get error deleting the image */
          204         flushimage(d, 0);
          205         a = bufimage(d, 1+4);
          206         if(a == 0)
          207                 return -1;
          208         a[0] = 'f';
          209         BPLONG(a+1, i->id);
          210         if(i->screen){
          211                 w = d->windows;
          212                 if(w == i)
          213                         d->windows = i->next;
          214                 else
          215                         while(w){
          216                                 if(w->next == i){
          217                                         w->next = i->next;
          218                                         break;
          219                                 }
          220                                 w = w->next;
          221                         }
          222         }
          223         if(flushimage(d, i->screen!=0) < 0)
          224                 return -1;
          225 
          226         return 0;
          227 }
          228 
          229 int
          230 freeimage(Image *i)
          231 {
          232         int ret;
          233 
          234         if(i == nil)
          235                 return 0;
          236         if(i == screen)
          237                 abort();
          238         ret = _freeimage1(i);
          239         free(i);
          240         return ret;
          241 }