Magellan Linux

Annotation of /trunk/linterm_tools/fw_builder/bootsplash/splash.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 658 - (hide annotations) (download)
Mon Jan 14 16:57:24 2008 UTC (16 years, 4 months ago) by niro
File MIME type: text/plain
File size: 11953 byte(s)
initial import

1 niro 658 /* Splash control program.
2     *
3     * (c) 2001, 2002, 2003 by Stefan Reinauer <stepan@suse.de>
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * as published by the Free Software Foundation; either version
8     * 2 of the License, or (at your option) any later version.
9     *
10     */
11    
12     #include <sys/types.h>
13     #include <sys/stat.h>
14     #include <fcntl.h>
15     #include <unistd.h>
16     #include <errno.h>
17     #include <stdio.h>
18     #include <string.h>
19     #include <stdlib.h>
20     #include <libgen.h>
21     #include <getopt.h>
22    
23    
24     #define PROCSPLASH "/proc/splash"
25     #define BUFSIZE 4096
26     #if 1
27     #define DEBUG(x...)
28     #else
29     #define DEBUG(x...) printf(x)
30     #endif
31    
32     long unit = 0;
33     long version = 1;
34     long state = -1;
35     long fgcolor = -1;
36     long bgcolor = -1;
37     long tx = -1;
38     long ty = -1;
39     long tw = -1;
40     long th = -1;
41     long px = 0;
42     long py = 0;
43     long pw = 0;
44     long ph = 0;
45     long pr = 0;
46     long pg = 0;
47     long pb = 0;
48     long pa = 160;
49     long pf = 1;
50     long pc = 0x141464;
51     long ptl = 0xffff;
52     long pbr = 0x00;
53     long ax = 0;
54     long ay = 0;
55     long progress = 0;
56     long overpaintok = 0;
57     long percent = 0;
58     long text = 0;
59     char *jpgfile = 0;
60     char *silentjpgfile = 0;
61     char splashdscname[512];
62    
63     int boxcount;
64     unsigned char boxes[12 * 256];
65     int sboxcount;
66     unsigned char sboxes[12 * 256];
67    
68     struct parstab {
69     char *name;
70     long *val;
71     char **str;
72     } parstab[] = {
73     { "unit", &unit },
74     { "version", &version },
75     { "state", &state },
76     { "fgcolor", &fgcolor },
77     { "bgcolor", &bgcolor },
78     /* v1+ */
79     { "tx", &tx },
80     { "ty", &ty },
81     { "tw", &tw },
82     { "th", &th },
83     /* v2+ */
84     { "px", &px },
85     { "py", &py },
86     { "pw", &pw },
87     { "ph", &ph },
88     { "pr", &pr },
89     { "pg", &pg },
90     { "pb", &pb },
91     { "ax", &ax },
92     { "ay", &ay },
93     /* v3+ */
94     /* independant */
95     { "progress_enable", &progress },
96     { "progress_x", &progress },
97     { "progress_y", &progress },
98     { "progress_width", &progress },
99     { "progress_height", &progress },
100     { "progress_fgcolor", &progress },
101     { "progress_bgcolor", &progress },
102     { "text_size", &text },
103     { "text_color", &text },
104     { "text_x", &text },
105     { "text_y", &text },
106     { "text_font", (long *) 0 },
107     { "silentjpeg", (long *) 0, &silentjpgfile },
108     { "percent", &percent },
109     { "overpaintok", &overpaintok },
110     { "jpeg", (long *) 0, &jpgfile },
111     { (char *) 0, (long *) 0 }
112     };
113    
114     void parsebox(char *pl)
115     {
116     int co[4];
117     int i, j, c, d = 0;
118     char cols[16];
119     unsigned char *bp;
120     int boxcnt;
121     int isibox = 0;
122     int *boxcntp;
123     unsigned char *boxptr;
124     char *p = pl + 3;
125     int noover = 0;
126     int hidemax = 0;
127    
128     boxcntp = &boxcount;
129     boxptr = boxes;
130     for (i = 0; i < 4; i++) {
131     if (*p != ' ' && *p != '\t' && *p != '=') {
132     fprintf(stderr, "syntax error: '%c' %s\n", *p, pl);
133     exit(1);
134     }
135     while (*p == ' ' || *p == '\t' || *p == '=')
136     p++;
137     if (i == 0 && !strncmp(p, "silent", 6)) {
138     i--;
139     boxcntp = &sboxcount;
140     boxptr = sboxes;
141     p += 6;
142     continue;
143     }
144     if (i == 0 && !strncmp(p, "inter", 5)) {
145     i--;
146     isibox = 1;
147     p += 5;
148     continue;
149     }
150     if (i == 0 && !strncmp(p, "noover", 6)) {
151     i--;
152     noover = 1;
153     p += 6;
154     continue;
155     }
156     if (i == 0 && !strncmp(p, "hidemax", 7)) {
157     i--;
158     hidemax = 1;
159     p += 7;
160     continue;
161     }
162     co[i] = strtol(p, (char **) NULL, 0);
163     while (*p == 'x' || (*p >= '0' && *p <= '9')
164     || (*p >= 'a' && *p <= 'f') || (*p >= 'A'
165     && *p <= 'F'))
166     p++;
167     }
168     for (i = 0; i < 4; i++) {
169     if (*p != ' ' && *p != '\t') {
170     fprintf(stderr, "syntax error: %s\n", pl);
171     exit(1);
172     }
173     while (*p == ' ' || *p == '\t')
174     p++;
175     if (i == 1 && *p == 0)
176     break;
177     if (*p++ != '#') {
178     fprintf(stderr, "syntax error: %s\n", pl);
179     exit(1);
180     }
181     for (j = 0; j < 8; j++) {
182     c = *p++;
183     if (c >= '0' && c <= '9')
184     c -= '0';
185     else if (c >= 'a' && c <= 'f')
186     c -= 'a' - 10;
187     else if (c >= 'A' && c <= 'F')
188     c -= 'A' - 10;
189     else {
190     fprintf(stderr, "syntax error: %s\n", pl);
191     exit(1);
192     }
193     if (!(j & 1)) {
194     d = c;
195     continue;
196     }
197     c += d << 4;
198     cols[i * 4 + (j >> 1)] = c;
199     if (j == 5 && (*p == 0 || *p == ' ' || *p == '\t')) {
200     cols[i * 4 + 3] = 255;
201     break;
202     }
203     }
204     if (*p == 0 && i == 0) {
205     i = 1;
206     break;
207     }
208     }
209     while (*p == ' ' || *p == '\t')
210     p++;
211     if (*p) {
212     fprintf(stderr, "syntax error: %s\n", pl);
213     exit(1);
214     }
215     boxcnt = *boxcntp;
216     if (boxcnt >= 254) {
217     fprintf(stderr, "too many boxes\n");
218     exit(1);
219     }
220     bp = boxptr + 12 * boxcnt++;
221     if (isibox)
222     co[0] = ~co[0];
223     if (i > 1) {
224     co[1] = ~co[1];
225     boxcnt++;
226     }
227     if (noover)
228     co[2] = ~co[2];
229     if (hidemax)
230     co[3] = ~co[3];
231     *bp++ = co[0] & 255;
232     *bp++ = co[0] >> 8;
233     *bp++ = co[1] & 255;
234     *bp++ = co[1] >> 8;
235     *bp++ = co[2] & 255;
236     *bp++ = co[2] >> 8;
237     *bp++ = co[3] & 255;
238     *bp++ = co[3] >> 8;
239     for (j = 0; j < i * 4; j++)
240     *bp++ = cols[j];
241     *boxcntp = boxcnt;
242     }
243    
244     void setsplash(char *cfgfile, int filterflag, int verbose_only)
245     {
246     struct stat stb;
247     char buf[256];
248     char *p;
249     int l, size, fd;
250     FILE *fp = 0;
251     FILE *sfp = 0;
252     struct parstab *pt;
253     unsigned char *pic;
254     int silentl = 0;
255    
256     if (cfgfile) {
257     if ((fp = fopen(cfgfile, "r")) == 0) {
258     perror(cfgfile);
259     exit(1);
260     }
261     while (fgets(buf, sizeof(buf), fp)) {
262     l = strlen(buf);
263     if (l == 0)
264     continue;
265     if (l == sizeof(buf) - 1) {
266     fprintf(stderr, "line too long\n");
267     exit(1);
268     }
269     buf[--l] = 0;
270     while (l
271     && (buf[l - 1] == ' '
272     || (buf[l - 1] == '\t')))
273     buf[--l] = 0;
274     for (p = buf; *p == ' ' || *p == '\t'; p++);
275     if (*p == 0 || *p == '#')
276     continue;
277     if (!strncmp(p, "box", 3)) {
278     parsebox(p);
279     continue;
280     }
281     for (pt = parstab; pt->name; pt++) {
282     l = strlen(pt->name);
283     if (!strncmp(p, pt->name, l)
284     && (p[l] == ' ' || p[l] == '\t'
285     || p[l] == '='))
286     break;
287     }
288     if (!pt->name) {
289     fprintf(stderr, "syntax error: %s\n", p);
290     exit(1);
291     }
292     while (p[l] == ' ' || p[l] == '\t')
293     l++;
294     if (p[l++] != '=') {
295     fprintf(stderr, "syntax error: %s\n", p);
296     exit(1);
297     }
298     while (p[l] == ' ' || p[l] == '\t')
299     l++;
300     if (pt->val)
301     *pt->val =
302     strtol(p + l, (char **) NULL, 0);
303     else
304     *pt->str = strdup(p + l);
305     }
306     fclose(fp);
307     if (!jpgfile) {
308     l = strlen(cfgfile);
309     if (l > 4 && !strcmp(cfgfile + l - 4, ".cfg")) {
310     jpgfile = strdup(cfgfile);
311     strcpy(jpgfile + l - 4, ".jpg");
312     p = strstr(jpgfile, "config");
313     if (p)
314     strncpy(p, "images", 6);
315     }
316     }
317    
318     if (tx == 0 && ty == 0 && tw == 0 && th == 0) {
319     tx = px + 8;
320     ty = py + 4;
321     tw = pw - 16;
322     th = ph - 8;
323     }
324    
325     if (jpgfile
326     && (*jpgfile == 0 || tx < 0 || ty < 0 || tw <= 0
327     || th <= 0)) {
328     free(jpgfile);
329     jpgfile = 0;
330     }
331     }
332    
333     if (verbose_only)
334     silentjpgfile = NULL;
335    
336    
337     if (silentjpgfile && jpgfile) {
338     if ((sfp = fopen(silentjpgfile, "r")) == 0) {
339     perror(silentjpgfile);
340     exit(1);
341     }
342     if (fstat(fileno(sfp), &stb) == -1) {
343     perror("fstat");
344     exit(1);
345     }
346     silentl = stb.st_size;
347     }
348    
349     if (jpgfile) {
350     if ((fp = fopen(jpgfile, "r")) == 0) {
351     perror(jpgfile);
352     exit(1);
353     }
354     if (fstat(fileno(fp), &stb) == -1) {
355     perror("fstat");
356     exit(1);
357     }
358     l = stb.st_size;
359     pic =
360     calloc(47 + l + silentl + boxcount * 12 +
361     sboxcount * 12, 1);
362     if (pic == 0) {
363     fprintf(stderr, "Out of memory.\n");
364     exit(1);
365     }
366     if (fread(pic + 47 + boxcount * 12, l, 1, fp) != 1) {
367     perror("fread");
368     exit(1);
369     }
370     if (silentjpgfile) {
371     if (fread
372     (pic + 47 + l + boxcount * 12 + sboxcount * 12,
373     silentl, 1, sfp) != 1) {
374     perror("fread");
375     exit(1);
376     }
377     fclose(sfp);
378     if (sboxcount)
379     memmove(pic + 47 + l + boxcount * 12,
380     sboxes, sboxcount * 12);
381     silentl += sboxcount * 12;
382     l += silentl;
383     }
384     fclose(fp);
385     } else {
386     l = 0;
387     pic = calloc(47, 1);
388     if (pic == 0) {
389     fprintf(stderr, "Out of memory.\n");
390     exit(1);
391     }
392     }
393     size = l;
394     if (version < 1 || version > 3) {
395     fprintf(stderr, "Illegal version: %ld\n", version);
396     exit(1);
397     }
398     if (version == 1 && unit != 0) {
399     /* convert to version 2 */
400     tx *= 8;
401     ty *= 16;
402     tw *= 8;
403     th *= 16;
404     px = tx + 10;
405     py = ty + 10;
406     pw = tw - 20;
407     ph = th - 20;
408     pr = pg = pb = 240;
409     state = 1;
410     fgcolor = 0;
411     bgcolor = 15;
412     version = 2;
413     }
414     if (version == 1) {
415     /* write version 1 file */
416     strcpy(pic, "BOOTSPL1");
417     pic[8] = tx;
418     pic[9] = tx >> 8;
419     pic[10] = ty;
420     pic[11] = ty >> 8;
421     pic[12] = tw;
422     pic[13] = tw >> 8;
423     pic[14] = th;
424     pic[15] = th >> 8;
425     pic[16] = size;
426     pic[17] = size >> 8;
427     pic[18] = size >> 16;
428     pic[19] = size >> 24;
429     if (l > 0)
430     memmove(pic + 20, pic + 47, l);
431     l += 20;
432     } else if (version == 2) {
433     /* write version 2 file */
434     strcpy(pic, "BOOTSPL2");
435     pic[8] = unit;
436     pic[9] = state;
437     pic[10] = fgcolor;
438     pic[11] = bgcolor;
439     if (cfgfile && size == 0
440     && (state != -1 || fgcolor != -1 || bgcolor != -1))
441     size = -1;
442     pic[12] = size;
443     pic[13] = size >> 8;
444     pic[14] = size >> 16;
445     pic[15] = size >> 24;
446     pic[16] = tx;
447     pic[17] = tx >> 8;
448     pic[18] = ty;
449     pic[19] = ty >> 8;
450     pic[20] = tw;
451     pic[21] = tw >> 8;
452     pic[22] = th;
453     pic[23] = th >> 8;
454     pic[24] = px;
455     pic[25] = px >> 8;
456     pic[26] = py;
457     pic[27] = py >> 8;
458     pic[28] = pw;
459     pic[29] = pw >> 8;
460     pic[30] = ph;
461     pic[31] = ph >> 8;
462     pic[32] = pr;
463     pic[33] = pg;
464     pic[34] = pb;
465     if (l > 0)
466     memmove(pic + 35, pic + 47, l);
467     l += 35;
468     } else { /* version 3 */
469     strcpy(pic, "BOOTSPL3");
470     pic[8] = unit;
471     pic[9] = state;
472     pic[10] = fgcolor;
473     pic[11] = bgcolor;
474     size += boxcount * 12;
475     if (cfgfile && size == 0
476     && (state != -1 || fgcolor != -1 || bgcolor != -1))
477     size = -1;
478     pic[12] = size;
479     pic[13] = size >> 8;
480     pic[14] = size >> 16;
481     pic[15] = size >> 24;
482     pic[16] = tx;
483     pic[17] = tx >> 8;
484     pic[18] = ty;
485     pic[19] = ty >> 8;
486     pic[20] = tw;
487     pic[21] = tw >> 8;
488     pic[22] = th;
489     pic[23] = th >> 8;
490     pic[24] = boxcount;
491     pic[25] = boxcount >> 8;
492     pic[28] = silentl;
493     pic[29] = silentl >> 8;
494     pic[30] = silentl >> 16;
495     pic[31] = silentl >> 24;
496     pic[32] = sboxcount;
497     pic[33] = sboxcount >> 8;
498     pic[34] = percent;
499     pic[35] = percent >> 8;
500     pic[36] = overpaintok;
501     pic[37] = 0; /* numpalette */
502     if (l > 0)
503     memmove(pic + 38 + boxcount * 12,
504     pic + 47 + boxcount * 12, l);
505     if (boxcount)
506     memmove(pic + 38, boxes, boxcount * 12);
507     l += 38 + boxcount * 12;
508     }
509    
510     if (filterflag)
511     fd = 1;
512     else if ((fd = open(PROCSPLASH, O_WRONLY)) == -1) {
513     perror(PROCSPLASH);
514     exit(1);
515     }
516     if (write(fd, pic, l) != l) {
517     perror("write");
518     exit(1);
519     }
520     if (!filterflag)
521     close(fd);
522     free(pic);
523     }
524    
525     int main(int argc, char *argv[])
526     {
527     int procsplash, c;
528     int setflag = 0;
529     int errflag = 0;
530     int filterflag = 0;
531     int verbose_only = 0;
532     unsigned char *readbuffer;
533    
534     while ((c = getopt(argc, argv, "fsu:n")) != EOF) {
535     switch (c) {
536     case 's':
537     setflag = 1;
538     break;
539     case 'f':
540     filterflag = 1;
541     break;
542     case 'u':
543     unit = atoi(optarg);
544     break;
545     case 'n':
546     verbose_only = 1;
547     break;
548     case '?':
549     errflag = 1;
550     break;
551     }
552     }
553    
554     if (errflag
555     || (argc != optind + 1 && (argc != optind || !setflag))) {
556     printf("Usage: %s -s [-u unit] -n [cfgfile]\n", argv[0]);
557     return 0;
558     }
559    
560     readbuffer = malloc(BUFSIZE);
561    
562     if (!readbuffer) {
563     DEBUG("splash: Not enough memory.\n");
564     return -ENOMEM;
565     }
566    
567     if (!setflag || !filterflag) {
568     procsplash = open(PROCSPLASH, O_RDONLY);
569     if (procsplash < 0) {
570     if (setflag) {
571     perror(PROCSPLASH);
572     exit(1);
573     }
574     DEBUG("splash: File %s not available.\n",
575     PROCSPLASH);
576     return 0;
577     }
578    
579     if (read(procsplash, readbuffer, BUFSIZE) < 0) {
580     if (setflag)
581     perror("read");
582     DEBUG("splash: Read error in file %s.\n",
583     PROCSPLASH);
584     return -EBUSY;
585     }
586     close(procsplash);
587     }
588     if (setflag) {
589     if (!filterflag
590     && !strncmp(readbuffer, "Splash screen v0", 16)) {
591     fprintf(stderr,
592     "Your kernel support for the bootsplash is too old. Get the new version from http://www.bootsplash.org/\n");
593     exit(1);
594     }
595     setsplash(argc > optind ? argv[optind] : 0, filterflag,
596     verbose_only);
597     exit(0);
598     }
599    
600     return 0;
601     }