]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/spred/pal.c
upas/fs: remove useless loop in rf822()
[plan9front.git] / sys / src / cmd / spred / pal.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <thread.h>
5 #include <draw.h>
6 #include <mouse.h>
7 #include <keyboard.h>
8 #include <frame.h>
9 #include "dat.h"
10 #include "fns.h"
11
12 Pal *
13 newpal(char *f)
14 {
15         Pal *p;
16         
17         p = emalloc(sizeof(*p));
18         p->type = PAL;
19         p->sel = -1;
20         filinit(p, f);
21         return p;
22 }
23
24 void
25 putpal(Pal *p)
26 {
27         int i;
28
29         for(i = 0; i < p->ncol; i++)
30                 freeimage(p->ims[i]);
31         free(p->cols);
32         free(p->ims);
33 }
34
35 int
36 readpal(Pal *p, Biobuf *bp)
37 {
38         char *s, *sp;
39         char *args[8];
40         int nc, i, c;
41         
42         s = nil;
43         if(tline(bp, &s, args, nelem(args)) != 2)
44                 goto err;
45         if(strcmp(args[0], "pal") != 0)
46                 goto err;
47         nc = strtol(args[1], &sp, 0);
48         if(*sp != 0 || nc < 0)
49                 goto err;
50         free(s);
51         s = nil;
52         p->ncol = nc;
53         p->cols = emalloc(nc * sizeof(*p->cols));
54         p->ims = emalloc(nc * sizeof(*p->ims));
55         for(i = 0; i < nc; i++){
56                 if(tline(bp, &s, args, nelem(args)) != 1)
57                         goto err;
58                 c = strtol(args[0], &sp, 0);
59                 if(*sp != 0 || c < 0 || c > 0xffffff)
60                         goto err;
61                 p->cols[i] = c;
62                 free(s);
63                 s = nil;
64         }
65         for(i = 0; i < nc; i++)
66                 p->ims[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, p->cols[i] << 8 | 0xff);
67         p->id = getident(bp->fid);
68         return 0;
69 err:
70         if(s != nil)
71                 free(s);
72         werrstr("invalid format");
73         return -1;
74 }
75
76 int
77 writepal(Pal *p, char *f)
78 {
79         Biobuf *bp;
80         int i, rc, n;
81
82         if(f == nil)
83                 f = p->name;
84         bp = Bopen(f, OWRITE);
85         if(bp == nil){
86                 cmdprint("?%r\n");
87                 return -1;
88         }
89         n = 0;
90         rc = Bprint(bp, "pal %d\n", p->ncol);
91         if(rc < 0) goto err;
92         n += rc;
93         for(i = 0; i < p->ncol; i++){
94                 rc = Bprint(bp, "%#.6x\n", p->cols[i]);
95                 if(rc < 0) goto err;
96                 n += rc;
97         }
98         if(Bterm(bp) < 0){
99                 cmdprint("?%r\n");
100                 return -1;
101         }
102         p->change = 0;
103         cmdprint("%s: #%d\n", f, n);
104         return 0;
105 err:
106         cmdprint("?%r\n");
107         Bterm(bp);
108         return -1;
109 }
110
111 Pal *
112 findpal(char *sf, char *fn, int op)
113 {
114         File *f;
115         char *s, *q;
116         Ident i;
117         int fd;
118         Biobuf *bp;
119         Pal *p;
120         
121         if(sf == nil)
122                 sf = "";
123         s = emalloc(strlen(sf) + strlen(fn) + 2);
124         strcpy(s, sf);
125         q = strrchr(s, '/');
126         if(q != nil)
127                 *++q = 0;
128         else
129                 *s = 0;
130         strcpy(s, fn);
131         fd = open(s, OREAD);
132         if(fd < 0){
133                 free(s);
134                 return nil;
135         }
136         i = getident(fd);
137         if(i.type == (uint)-1){
138                 close(fd);
139                 return nil;
140         }
141         for(f = flist.next; f != &flist; f = f->next)
142                 if(f->type == PAL && identcmp(&f->id, &i) == 0){
143                         close(fd);
144                         putident(i);
145                         return (Pal *) f;
146                 }
147         putident(i);
148         if(op == 0){
149                 close(fd);
150                 return nil;
151         }
152         bp = emalloc(sizeof(*bp));
153         Binit(bp, fd, OREAD);
154         p = newpal(s);
155         if(readpal(p, bp) < 0){
156                 putfil(p);
157                 p = nil;
158                 goto end;
159         }
160 end:
161         Bterm(bp);
162         close(fd);
163         free(bp);
164         free(s);
165         return p;
166 }
167
168 static void
169 palredraw(Pal *p)
170 {
171         File *f;
172
173         filredraw(p);
174         for(f = flist.next; f != &flist; f = f->next)
175                 if(f->type == SPR && ((Spr *) f)->pal == p)
176                         filredraw(f);
177 }
178
179 void
180 palsize(Pal *p, int sz, int ch)
181 {
182         int i;
183
184         if(sz == p->ncol)
185                 return;
186         p->cols = realloc(p->cols, sz * sizeof(*p->cols));
187         p->ims = realloc(p->ims, sz * sizeof(*p->ims));
188         if(sz > p->ncol)
189                 for(i = p->ncol; i < sz; i++){
190                         p->cols[i] = 0;
191                         p->ims[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0);
192                 }
193         p->ncol = sz;
194         if(ch)
195                 change(p);
196         palredraw(p);
197 }
198
199 void
200 paldraw(Win *w)
201 {
202         Pal *p;
203         int n, i;
204         Rectangle r;
205         
206         if(w->type != PAL || w->f == nil)
207                 sysfatal("paldraw: phase error");
208         p = (Pal *) w->f;
209         n = Dx(w->inner) / w->zoom;
210         draw(w->im, w->inner, w->tab->cols[BACK], nil, ZP);
211         for(i = 0; i < p->ncol; i++){
212                 r.min = addpt(w->inner.min, mulpt(Pt(i%n, i/n), w->zoom));
213                 r.max.x = r.min.x + w->zoom;
214                 r.max.y = r.min.y + w->zoom;
215                 draw(w->im, r, p->ims[i], nil, ZP);
216                 if(p->sel == i)
217                         border(w->im, r, SELSIZ, display->white, ZP);
218         }
219 }
220
221 void
222 palset(Pal *p, int s, u32int c)
223 {
224         if(s < 0 || s >= p->ncol || p->cols[s] == c)
225                 return;
226         p->cols[s] = c;
227         freeimage(p->ims[s]);
228         p->ims[s] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, c << 8 | 0xff);
229         change(p);
230         palredraw(p);
231 }
232
233 static int
234 palinit(Win *w)
235 {
236         w->zoom = 32;
237         return 0;
238 }
239
240 static void
241 palzerox(Win *w, Win *v)
242 {
243         v->zoom = w->zoom;
244 }
245
246 static void
247 palclick(Win *w, Mousectl *mc)
248 {
249         int n, i;
250         Point pt;
251         Pal *p;
252         
253         if(!ptinrect(mc->xy, w->inner))
254                 return;
255         if(w->f == nil)
256                 sysfatal("palclick: phase error");
257         p = (Pal *) w->f;
258         n = Dx(w->inner) / w->zoom;
259         pt = subpt(mc->xy, w->inner.min);
260         if(pt.x >= n * w->zoom)
261                 return;
262         i = pt.x / w->zoom + pt.y / w->zoom * n;
263         if(i >= p->ncol)
264                 return;
265         p->sel = i;
266         palredraw(p);
267 }
268
269 Wintab paltab = {
270         .init = palinit,
271         .click = palclick,
272         .draw = paldraw,
273         .zerox = palzerox,
274         .hexcols = {
275                 [BORD] 0xAA0000FF,
276                 [DISB] 0xCC8888FF,
277                 [BACK] 0xFFCCFFFF,
278         },
279 };