talloc.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
talloc.c (4188B)
---
     1 #include 
     2 #include 
     3 #include 
     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 }