Disable progress bar and center logo
[profile/ivi/psplash.git] / psplash.c
1 /* 
2  *  pslash - a lightweight framebuffer splashscreen for embedded devices. 
3  *
4  *  Copyright (c) 2006 Matthew Allum <mallum@o-hand.com>
5  *
6  *  Parts of this file ( fifo handling ) based on 'usplash' copyright 
7  *  Matthew Garret.
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2, or (at your option)
12  *  any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  */
20
21 #include "psplash.h"
22 #include "psplash-poky-img.h"
23 #include "psplash-bar-img.h"
24 #include "radeon-font.h"
25
26 #define MSG ""
27
28 void
29 psplash_exit (int signum)
30 {
31   DBG("mark");
32
33   psplash_console_reset ();
34 }
35
36 void
37 psplash_draw_msg (PSplashFB *fb, const char *msg)
38 {
39   int w, h;
40
41   psplash_fb_text_size (fb, &w, &h, &radeon_font, msg);
42
43   DBG("displaying '%s' %ix%i\n", msg, w, h);
44
45   /* Clear */
46
47   psplash_fb_draw_rect (fb, 
48                         0, 
49                         fb->height - (fb->height/6) - h, 
50                         fb->width,
51                         h,
52                         PSPLASH_BACKGROUND_COLOR);
53
54   psplash_fb_draw_text (fb,
55                         (fb->width-w)/2, 
56                         fb->height - (fb->height/6) - h,
57                         PSPLASH_TEXT_COLOR,
58                         &radeon_font,
59                         msg);
60 }
61
62 void
63 psplash_draw_progress (PSplashFB *fb, int value)
64 {
65   int x, y, width, height, barwidth;
66
67   /* 4 pix border */
68   x      = ((fb->width  - BAR_IMG_WIDTH)/2) + 4 ;
69   y      = fb->height - (fb->height/6) + 4;
70   width  = BAR_IMG_WIDTH - 8; 
71   height = BAR_IMG_HEIGHT - 8;
72
73   if (value > 0)
74     {
75       barwidth = (CLAMP(value,0,100) * width) / 100;
76       psplash_fb_draw_rect (fb, x + barwidth, y, 
77                         width - barwidth, height,
78                         PSPLASH_BAR_BACKGROUND_COLOR);
79       psplash_fb_draw_rect (fb, x, y, barwidth,
80                             height, PSPLASH_BAR_COLOR);
81     }
82   else
83     {
84       barwidth = (CLAMP(-value,0,100) * width) / 100;
85       psplash_fb_draw_rect (fb, x, y, 
86                         width - barwidth, height,
87                         PSPLASH_BAR_BACKGROUND_COLOR);
88       psplash_fb_draw_rect (fb, x + width - barwidth,
89                             y, barwidth, height,
90                             PSPLASH_BAR_COLOR);
91     }
92
93   DBG("value: %i, width: %i, barwidth :%i\n", value, 
94                 width, barwidth);
95 }
96
97 static int 
98 parse_command (PSplashFB *fb, char *string, int length) 
99 {
100   char *command;
101   int   parsed=0;
102
103   parsed = strlen(string)+1;
104
105   DBG("got cmd %s", string);
106         
107   if (strcmp(string,"QUIT") == 0)
108     return 1;
109
110   command = strtok(string," ");
111
112   if (!strcmp(command,"PROGRESS")) 
113     {
114       psplash_draw_progress (fb, atoi(strtok(NULL,"\0")));
115     } 
116   else if (!strcmp(command,"MSG")) 
117     {
118       psplash_draw_msg (fb, strtok(NULL,"\0"));
119     } 
120   else if (!strcmp(command,"QUIT")) 
121     {
122       return 1;
123     }
124
125   return 0;
126 }
127
128 void 
129 psplash_main (PSplashFB *fb, int pipe_fd, int timeout) 
130 {
131   int            err;
132   ssize_t        length = 0;
133   fd_set         descriptors;
134   struct timeval tv;
135   char          *end;
136   char           command[2048];
137
138   tv.tv_sec = timeout;
139   tv.tv_usec = 0;
140
141   FD_ZERO(&descriptors);
142   FD_SET(pipe_fd, &descriptors);
143
144   end = command;
145
146   while (1) 
147     {
148       if (timeout != 0) 
149         err = select(pipe_fd+1, &descriptors, NULL, NULL, &tv);
150       else
151         err = select(pipe_fd+1, &descriptors, NULL, NULL, NULL);
152       
153       if (err <= 0) 
154         {
155           /*
156           if (errno == EINTR)
157             continue;
158           */
159           return;
160         }
161       
162       length += read (pipe_fd, end, sizeof(command) - (end - command));
163
164       if (length == 0) 
165         {
166           /* Reopen to see if there's anything more for us */
167           close(pipe_fd);
168           pipe_fd = open(PSPLASH_FIFO,O_RDONLY|O_NONBLOCK);
169           goto out;
170         }
171       
172       if (command[length-1] == '\0') 
173         {
174           if (parse_command(fb, command, strlen(command))) 
175             return;
176           length = 0;
177         } 
178       else if (command[length-1] == '\n') 
179         {
180           command[length-1] = '\0';
181           if (parse_command(fb, command, strlen(command))) 
182             return;
183           length = 0;
184         } 
185
186
187     out:
188       end = &command[length];
189     
190       tv.tv_sec = timeout;
191       tv.tv_usec = 0;
192       
193       FD_ZERO(&descriptors);
194       FD_SET(pipe_fd,&descriptors);
195     }
196
197   return;
198 }
199
200 int 
201 main (int argc, char** argv) 
202 {
203   char      *tmpdir;
204   int        pipe_fd, i = 0, angle = 0, ret = 0;
205   PSplashFB *fb;
206   bool       disable_console_switch = FALSE;
207   
208   signal(SIGHUP, psplash_exit);
209   signal(SIGINT, psplash_exit);
210   signal(SIGQUIT, psplash_exit);
211
212   while (++i < argc)
213     {
214       if (!strcmp(argv[i],"-n") || !strcmp(argv[i],"--no-console-switch"))
215         {
216           disable_console_switch = TRUE;
217           continue;
218         }
219
220       if (!strcmp(argv[i],"-a") || !strcmp(argv[i],"--angle"))
221         {
222           if (++i >= argc) goto fail;
223           angle = atoi(argv[i]);
224           continue;
225         }
226       
227     fail:
228       fprintf(stderr, 
229               "Usage: %s [-n|--no-console-switch][-a|--angle <0|90|180|270>]\n", 
230               argv[0]);
231       exit(-1);
232     }
233
234   tmpdir = getenv("TMPDIR");
235
236   if (!tmpdir)
237     tmpdir = "/tmp";
238
239   chdir(tmpdir);
240
241   if (mkfifo(PSPLASH_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP))
242     {
243       if (errno!=EEXIST) 
244         {
245           perror("mkfifo");
246           exit(-1);
247         }
248     }
249
250   pipe_fd = open (PSPLASH_FIFO,O_RDONLY|O_NONBLOCK);
251   
252   if (pipe_fd==-1) 
253     {
254       perror("pipe open");
255       exit(-2);
256     }
257
258   if (!disable_console_switch)
259     psplash_console_switch ();
260
261   if ((fb = psplash_fb_new(angle)) == NULL) {
262           ret = -1;
263           goto fb_fail;
264   }
265
266   /* Clear the background with #ecece1 */
267   psplash_fb_draw_rect (fb, 0, 0, fb->width, fb->height,
268                         PSPLASH_BACKGROUND_COLOR);
269
270   /* Draw the Poky logo  */
271   psplash_fb_draw_image (fb, 
272                          (fb->width  - POKY_IMG_WIDTH)/2, 
273                          (fb->height - POKY_IMG_HEIGHT)/2,
274                          POKY_IMG_WIDTH,
275                          POKY_IMG_HEIGHT,
276                          POKY_IMG_BYTES_PER_PIXEL,
277                          POKY_IMG_RLE_PIXEL_DATA);
278 #if 0
279   /* Draw progress bar border */
280   psplash_fb_draw_image (fb, 
281                          (fb->width  - BAR_IMG_WIDTH)/2, 
282                          fb->height - (fb->height/6), 
283                          BAR_IMG_WIDTH,
284                          BAR_IMG_HEIGHT,
285                          BAR_IMG_BYTES_PER_PIXEL,
286                          BAR_IMG_RLE_PIXEL_DATA);
287
288   psplash_draw_progress (fb, 0);
289
290   psplash_draw_msg (fb, MSG);
291 #endif
292
293   psplash_main (fb, pipe_fd, 0);
294
295
296   psplash_fb_destroy (fb);
297
298  fb_fail:
299   unlink(PSPLASH_FIFO);
300
301   if (!disable_console_switch)
302     psplash_console_reset ();
303
304   return ret;
305 }