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 (3479B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <memdraw.h>
            5 
            6 #define poolalloc(a, b) malloc(b)
            7 #define poolfree(a, b) free(b)
            8 
            9 void
           10 memimagemove(void *from, void *to)
           11 {
           12         Memdata *md;
           13 
           14         md = *(Memdata**)to;
           15         if(md->base != from){
           16                 print("compacted data not right: #%p\n", md->base);
           17                 abort();
           18         }
           19         md->base = to;
           20 
           21         /* if allocmemimage changes this must change too */
           22         md->bdata = (uchar*)md->base+sizeof(Memdata*)+sizeof(ulong);
           23 }
           24 
           25 Memimage*
           26 allocmemimaged(Rectangle r, u32int chan, Memdata *md, void *X)
           27 {
           28         int d;
           29         u32int l;
           30         Memimage *i;
           31 
           32         if(Dx(r) <= 0 || Dy(r) <= 0){
           33                 werrstr("bad rectangle %R", r);
           34                 return nil;
           35         }
           36         if((d = chantodepth(chan)) == 0) {
           37                 werrstr("bad channel descriptor %.8lux", chan);
           38                 return nil;
           39         }
           40 
           41         l = wordsperline(r, d);
           42 
           43         i = mallocz(sizeof(Memimage), 1);
           44         if(i == nil)
           45                 return nil;
           46 
           47         i->X = X;
           48         i->data = md;
           49         i->zero = sizeof(u32int)*l*r.min.y;
           50 
           51         if(r.min.x >= 0)
           52                 i->zero += (r.min.x*d)/8;
           53         else
           54                 i->zero -= (-r.min.x*d+7)/8;
           55         i->zero = -i->zero;
           56         i->width = l;
           57         i->r = r;
           58         i->clipr = r;
           59         i->flags = 0;
           60         i->layer = nil;
           61         i->cmap = memdefcmap;
           62         if(memsetchan(i, chan) < 0){
           63                 free(i);
           64                 return nil;
           65         }
           66         return i;
           67 }
           68 
           69 Memimage*
           70 _allocmemimage(Rectangle r, u32int chan)
           71 {
           72         int d;
           73         u32int l, nw;
           74         uchar *p;
           75         Memdata *md;
           76         Memimage *i;
           77 
           78         if((d = chantodepth(chan)) == 0) {
           79                 werrstr("bad channel descriptor %.8lux", chan);
           80                 return nil;
           81         }
           82 
           83         l = wordsperline(r, d);
           84         nw = l*Dy(r);
           85         md = malloc(sizeof(Memdata));
           86         if(md == nil)
           87                 return nil;
           88 
           89         md->ref = 1;
           90         md->base = poolalloc(imagmem, sizeof(Memdata*)+(1+nw)*sizeof(ulong));
           91         if(md->base == nil){
           92                 free(md);
           93                 return nil;
           94         }
           95 
           96         p = (uchar*)md->base;
           97         *(Memdata**)p = md;
           98         p += sizeof(Memdata*);
           99 
          100         *(ulong*)p = getcallerpc(&r);
          101         p += sizeof(ulong);
          102 
          103         /* if this changes, memimagemove must change too */
          104         md->bdata = p;
          105         md->allocd = 1;
          106 
          107         i = allocmemimaged(r, chan, md, nil);
          108         if(i == nil){
          109                 poolfree(imagmem, md->base);
          110                 free(md);
          111                 return nil;
          112         }
          113         md->imref = i;
          114         return i;
          115 }
          116 
          117 void
          118 _freememimage(Memimage *i)
          119 {
          120         if(i == nil)
          121                 return;
          122         if(i->data->ref-- == 1 && i->data->allocd){
          123                 if(i->data->base)
          124                         poolfree(imagmem, i->data->base);
          125                 free(i->data);
          126         }
          127         free(i);
          128 }
          129 
          130 /*
          131  * Wordaddr is deprecated.
          132  */
          133 u32int*
          134 wordaddr(Memimage *i, Point p)
          135 {
          136         return (u32int*) ((ulong)byteaddr(i, p) & ~(sizeof(u32int)-1));
          137 }
          138 
          139 uchar*
          140 byteaddr(Memimage *i, Point p)
          141 {
          142         uchar *a;
          143 
          144         /* careful to sign-extend negative p.y for 64-bits */
          145         a = i->data->bdata+i->zero+(int)(sizeof(u32int)*p.y*i->width);
          146 
          147         if(i->depth < 8){
          148                 /*
          149                  * We need to always round down,
          150                  * but C rounds toward zero.
          151                  */
          152                 int np;
          153                 np = 8/i->depth;
          154                 if(p.x < 0)
          155                         return a+(p.x-np+1)/np;
          156                 else
          157                         return a+p.x/np;
          158         }
          159         else
          160                 return a+p.x*(i->depth/8);
          161 }
          162 
          163 int
          164 memsetchan(Memimage *i, u32int chan)
          165 {
          166         int d;
          167         int t, j, k;
          168         u32int cc;
          169         int bytes;
          170 
          171         if((d = chantodepth(chan)) == 0) {
          172                 werrstr("bad channel descriptor");
          173                 return -1;
          174         }
          175 
          176         i->depth = d;
          177         i->chan = chan;
          178         i->flags &= ~(Fgrey|Falpha|Fcmap|Fbytes);
          179         bytes = 1;
          180         for(cc=chan, j=0, k=0; cc; j+=NBITS(cc), cc>>=8, k++){
          181                 t=TYPE(cc);
          182                 if(t < 0 || t >= NChan){
          183                         werrstr("bad channel string");
          184                         return -1;
          185                 }
          186                 if(t == CGrey)
          187                         i->flags |= Fgrey;
          188                 if(t == CAlpha)
          189                         i->flags |= Falpha;
          190                 if(t == CMap && i->cmap == nil){
          191                         i->cmap = memdefcmap;
          192                         i->flags |= Fcmap;
          193                 }
          194 
          195                 i->shift[t] = j;
          196                 i->mask[t] = (1<<NBITS(cc))-1;
          197                 i->nbits[t] = NBITS(cc);
          198                 if(NBITS(cc) != 8)
          199                         bytes = 0;
          200         }
          201         i->nchan = k;
          202         if(bytes)
          203                 i->flags |= Fbytes;
          204         return 0;
          205 }