]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/mothra/getpix.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / mothra / getpix.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <event.h>
5 #include <panel.h>
6 #include "mothra.h"
7
8 typedef struct Pix Pix;
9 struct Pix{
10         Pix *next;
11         Image *b;
12         int width;
13         int height;
14         char name[NNAME];
15 };
16
17 char *pixcmd[]={
18 [GIF]   "gif -9t",
19 [JPEG]  "jpg -9t",
20 [PNG]   "png -9t",
21 [BMP]   "bmp -9t",
22 [ICO]   "ico -c",
23 };
24
25 void getimage(Rtext *t, Www *w){
26         int pfd[2];
27         Action *ap;
28         Url url;
29         Image *b;
30         int fd, typ;
31         char err[512], buf[80], *s;
32         Pix *p;
33
34         ap=t->user;
35         seturl(&url, ap->image, w->url->fullname);
36         for(p=w->pix;p!=nil; p=p->next)
37                 if(strcmp(ap->image, p->name)==0 && ap->width==p->width && ap->height==p->height){
38                         t->b = p->b;
39                         w->changed=1;
40                         return;
41                 }
42         fd=urlget(&url, -1);
43         if(fd==-1){
44         Err:
45                 snprint(err, sizeof(err), "[img: %s: %r]", url.reltext);
46                 free(t->text);
47                 t->text=strdup(err);
48                 w->changed=1;
49                 close(fd);
50                 return;
51         }
52         typ = snooptype(fd);
53         if(typ < 0 || typ >= nelem(pixcmd) || pixcmd[typ] == nil){
54                 werrstr("unknown image type");
55                 goto Err;
56         }
57         if((fd = pipeline(fd, "exec %s", pixcmd[typ])) < 0)
58                 goto Err;
59         if(ap->width>0 || ap->height>0){
60                 s = buf;
61                 s += sprint(s, "exec resize");
62                 if(ap->width>0)
63                         s += sprint(s, " -x %d", ap->width);
64                 if(ap->height>0)
65                         s += sprint(s, " -y %d", ap->height);
66                 if((fd = pipeline(fd, buf)) < 0)
67                         goto Err;
68         }
69         b=readimage(display, fd, 1);
70         if(b==0){
71                 werrstr("can't read image");
72                 goto Err;
73         }
74         close(fd);
75         p=emalloc(sizeof(Pix));
76         nstrcpy(p->name, ap->image, sizeof(p->name));
77         p->b=b;
78         p->width=ap->width;
79         p->height=ap->height;
80         p->next=w->pix;
81         w->pix=p;
82         t->b=b;
83         w->changed=1;
84 }
85
86 void getpix(Rtext *t, Www *w){
87         int i, pid, nworker, worker[NXPROC];
88         Action *ap;
89
90         nworker = 0;
91         for(i=0; i<nelem(worker); i++)
92                 worker[i] = -1;
93
94         for(;t!=0;t=t->next){
95                 ap=t->user;
96                 if(ap && ap->image){
97                         pid = rfork(RFFDG|RFPROC|RFMEM);
98                         switch(pid){
99                         case -1:
100                                 fprint(2, "fork: %r\n");
101                                 break;
102                         case 0:
103                                 getimage(t, w);
104                                 exits(0);
105                         default:
106                                 for(i=0; i<nelem(worker); i++)
107                                         if(worker[i] == -1){
108                                                 worker[i] = pid;
109                                                 nworker++;
110                                                 break;
111                                         }
112
113                                 while(nworker == nelem(worker)){
114                                         if((pid = waitpid()) < 0)
115                                                 break;
116                                         for(i=0; i<nelem(worker); i++)
117                                                 if(worker[i] == pid){
118                                                         worker[i] = -1;
119                                                         nworker--;
120                                                         break;
121                                                 }
122                                 }
123                         }
124                         
125                 }
126         }
127         while(nworker > 0){
128                 if((pid = waitpid()) < 0)
129                         break;
130                 for(i=0; i<nelem(worker); i++)
131                         if(worker[i] == pid){
132                                 worker[i] = -1;
133                                 nworker--;
134                                 break;
135                         }
136         }
137 }
138
139 ulong countpix(void *p){
140         ulong n=0;
141         Pix *x;
142         for(x = p; x; x = x->next)
143                 n += Dy(x->b->r)*bytesperline(x->b->r, x->b->depth);
144         return n;
145 }
146
147 void freepix(void *p){
148         Pix *x, *xx;
149         xx = p;
150         while(x = xx){
151                 xx = x->next;
152                 freeimage(x->b);
153                 free(x);
154         }
155 }