Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /* 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 }