~ubuntu-branches/ubuntu/edgy/usplash/edgy

« back to all changes in this revision

Viewing changes to libusplash.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-09-05 17:37:45 UTC
  • Revision ID: james.westby@ubuntu.com-20060905173745-cagv3esrab8pe18q
Tags: 0.4-16
* Incorporate extra graphical bling support
* Integrate textual input patches from David Härdeman
* Build library with -fPIC

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
#include <linux/vt.h>
 
23
#include <linux/limits.h>
23
24
 
24
25
#include <sys/select.h>
25
26
#include <sys/time.h>
35
36
#include <string.h>
36
37
#include <unistd.h>
37
38
#include <assert.h>
 
39
#include <signal.h>
38
40
 
39
41
#include "usplash_backend.h"
40
42
#include "usplash.h"
41
43
#include "usplash-theme.h"
42
44
 
 
45
sigset_t sigs;
 
46
#define blocksig() do{ sigprocmask(SIG_BLOCK, &sigs, NULL); } while(0)
 
47
#define unblocksig() do{ sigprocmask(SIG_UNBLOCK, &sigs, NULL); } while(0)
43
48
 
44
49
/* Prototypes of static functions */
45
50
void switch_console    (int vt);
53
58
void draw_text         (const char *string, size_t len);
54
59
void draw_line         (const char *string, size_t len);
55
60
void draw_status       (const char *string, size_t len, int mode);
 
61
int handle_input       (const char *string, size_t len, int quiet);
56
62
 
57
63
/* Non-static so that svgalib can call it. Damned svgalib. */
58
64
void usplash_restore_console   (void);
99
105
        ioctl (fd, VT_ACTIVATE, vt);
100
106
        ioctl (fd, VT_WAITACTIVE, vt);
101
107
        close (fd);
 
108
 
 
109
        close (STDIN_FILENO);
 
110
        open (vtname, O_RDONLY);
102
111
}
103
112
 
104
113
void
121
130
int usplash_setup (int xres, int yres)
122
131
{
123
132
        int ret;
 
133
    short ncolors;
124
134
        void *theme_handle;
125
 
        usplash_set_resolution (xres, yres);
126
135
 
127
136
        theme_handle = dlopen (USPLASH_THEME, RTLD_LAZY);
128
137
        if (theme_handle) {
135
144
                theme = &testcard_theme;
136
145
        }
137
146
 
 
147
    ncolors = theme->pixmap->ncols;
 
148
    if(xres == 0)
 
149
        xres = theme->pixmap->width;
 
150
    if(yres == 0)
 
151
        yres = theme->pixmap->height;
 
152
        ret = usplash_set_resolution (xres, yres);
 
153
        if (ret)
 
154
                return ret;
138
155
        ret = usplash_init ();
139
156
        if (ret)
140
157
                return ret;
 
158
    if (theme->init)
 
159
        theme->init();
141
160
 
142
161
        usplash_getdimensions (&usplash_xres, &usplash_yres);
143
162
        left_edge = (usplash_xres - theme->pixmap->width)  / 2;
147
166
 
148
167
        usplash_set_palette (theme->pixmap->ncols, theme->pixmap->palette);
149
168
 
 
169
    sigemptyset(&sigs);
 
170
    sigaddset(&sigs, SIGALRM);
150
171
        return 0;
151
172
}       
152
173
 
165
186
void
166
187
clear_screen (void)
167
188
{
168
 
        usplash_clear (0, 0, usplash_xres, usplash_yres, theme->background);
169
 
 
170
 
        usplash_put (left_edge, top_edge, theme->pixmap);
 
189
    blocksig();
 
190
    if (theme->clear_screen)
 
191
        theme->clear_screen();
 
192
    else {
 
193
            usplash_clear (0, 0, usplash_xres, usplash_yres, theme->background);
 
194
            usplash_put (left_edge, top_edge, theme->pixmap);
 
195
   }
 
196
   unblocksig();
171
197
}
172
198
 
173
199
 
174
200
void
175
201
clear_progressbar (void)
176
202
{
177
 
        int x1, y1, x2, y2;
178
 
 
179
 
        x1 = left_edge + theme->progressbar_x;
180
 
        y1 = top_edge + theme->progressbar_y;
181
 
 
182
 
        x2 = x1 + theme->progressbar_width;
183
 
        y2 = y1 + theme->progressbar_height;
184
 
 
185
 
        usplash_clear (x1, y1, x2, y2, theme->progressbar_background);
 
203
    if (theme->clear_progressbar)
 
204
        theme->clear_progressbar();
 
205
    else {
 
206
            int x1, y1, x2, y2;
 
207
 
 
208
            x1 = left_edge + theme->progressbar_x;
 
209
            y1 = top_edge + theme->progressbar_y;
 
210
 
 
211
            x2 = x1 + theme->progressbar_width;
 
212
            y2 = y1 + theme->progressbar_height;
 
213
 
 
214
            usplash_clear (x1, y1, x2, y2, theme->progressbar_background);
 
215
    }
186
216
}
187
217
 
188
218
void
189
219
draw_progressbar (int percentage)
190
220
{
191
 
        int x1, y1, x2, y2, xx, bg, fg;
192
 
 
193
 
        if (percentage < 0) {
194
 
                bg = theme->progressbar_foreground;
195
 
                fg = theme->progressbar_background;
196
 
                percentage = -percentage;
197
 
        } else {
198
 
                bg = theme->progressbar_background;
199
 
                fg = theme->progressbar_foreground;
200
 
        }
201
 
 
202
 
        if (percentage > 100)
203
 
                return;
204
 
 
205
 
 
206
 
        x1 = left_edge + theme->progressbar_x;
207
 
        y1 = top_edge + theme->progressbar_y;
208
 
 
209
 
        x2 = x1 + theme->progressbar_width;
210
 
        y2 = y1 + theme->progressbar_height;
211
 
 
212
 
        xx = x1 + ((theme->progressbar_width * percentage) / 100);
213
 
 
214
 
        usplash_clear (x1, y1, xx, y2, fg);
215
 
        usplash_clear (xx, y1, x2, y2, bg);
 
221
    blocksig();
 
222
        if (percentage > 100 || percentage < -100)
 
223
            return;
 
224
 
 
225
    if (theme->draw_progressbar)
 
226
        theme->draw_progressbar(percentage);
 
227
    else {
 
228
            int x1, y1, x2, y2, xx, bg, fg;
 
229
 
 
230
            if (percentage < 0) {
 
231
                    bg = theme->progressbar_foreground;
 
232
                    fg = theme->progressbar_background;
 
233
                    percentage = -percentage;
 
234
            } else {
 
235
                    bg = theme->progressbar_background;
 
236
                    fg = theme->progressbar_foreground;
 
237
            }
 
238
 
 
239
            x1 = left_edge + theme->progressbar_x;
 
240
            y1 = top_edge + theme->progressbar_y;
 
241
 
 
242
            x2 = x1 + theme->progressbar_width;
 
243
            y2 = y1 + theme->progressbar_height;
 
244
 
 
245
            xx = x1 + ((theme->progressbar_width * percentage) / 100);
 
246
 
 
247
            usplash_clear (x1, y1, xx, y2, fg);
 
248
            usplash_clear (xx, y1, x2, y2, bg);
 
249
    }
 
250
    unblocksig();
216
251
}
217
252
 
218
253
 
219
254
void
220
255
clear_text (void)
221
256
{
222
 
        int x1, y1, x2, y2;
223
 
 
224
 
        x1 = left_edge + theme->text_x;
225
 
        y1 = top_edge + theme->text_y;
226
 
 
227
 
        x2 = x1 + theme->text_width;
228
 
        y2 = y1 + theme->text_height;
229
 
 
230
 
        usplash_clear (x1, y1, x2, y2, theme->text_background);
 
257
    blocksig();
 
258
    if (theme->clear_text)
 
259
        theme->clear_text();
 
260
    else {
 
261
            int x1, y1, x2, y2;
 
262
 
 
263
            x1 = left_edge + theme->text_x;
 
264
            y1 = top_edge + theme->text_y;
 
265
 
 
266
            x2 = x1 + theme->text_width;
 
267
            y2 = y1 + theme->text_height;
 
268
 
 
269
            usplash_clear (x1, y1, x2, y2, theme->text_background);
 
270
    }
 
271
    unblocksig();
231
272
}
232
273
 
233
274
void
234
275
draw_text (const char *string, size_t len)
235
276
{
 
277
    blocksig();
 
278
    if (theme->draw_text)
 
279
        theme->draw_text(string, len);
 
280
    else {
236
281
        /* FIXME some kind of better word wrapping here, perhaps? */
237
282
#if 0
238
 
        while (len > theme->line_length) {
239
 
                draw_line (string, theme->line_length);
240
 
                string += theme->line_length;
241
 
                len -= theme->line_length;
242
 
        }
 
283
            while (len > theme->line_length) {
 
284
                    draw_line (string, theme->line_length);
 
285
                    string += theme->line_length;
 
286
                    len -= theme->line_length;
 
287
            }
243
288
#endif
244
289
 
245
 
        draw_line (string, len);
 
290
            draw_line (string, len);
 
291
    }   
 
292
    unblocksig();
246
293
}
247
294
 
248
295
void
268
315
                   theme->text_foreground, theme->text_background);
269
316
}
270
317
 
 
318
handle_input (const char *string, const size_t len, const int quiet)
 
319
{
 
320
        int i;
 
321
        char input;
 
322
        int x1, y1, x2, y2, xpos;
 
323
        ssize_t wlen;
 
324
        int fifo_outfd;
 
325
        char inputbuf[PIPE_BUF] = "";
 
326
        
 
327
        /* some variables which we'll need */
 
328
        x1 = left_edge + theme->text_x;
 
329
        x2 = x1 + theme->text_width;
 
330
        
 
331
        y2 = top_edge + theme->text_y + theme->text_height;
 
332
        y1 = y2 - theme->line_height;
 
333
        
 
334
        /* draw the prompt */
 
335
        draw_line (string, len);
 
336
        xpos = x1;
 
337
        for (i = 0; i < len; i++)
 
338
                xpos += usplash_getfontwidth (*(string + i));
 
339
        
 
340
        /* Get user input */
 
341
        for (i = 0; i < PIPE_BUF - 1; i++) {
 
342
                input = getchar ();
 
343
                if (input == '\n' || input == '\r' || input == '\0')
 
344
                        break;
 
345
                
 
346
                inputbuf[i] = input;
 
347
                
 
348
                if (quiet)
 
349
                        input = '*';
 
350
                
 
351
                /* Make sure the text doesn't overflow */
 
352
                if (xpos + usplash_getfontwidth (input) > x2) {
 
353
                        usplash_move (x1,
 
354
                                      top_edge + theme->text_y + 
 
355
                                      theme->line_height,
 
356
                                      x1,
 
357
                                      top_edge + theme->text_y,
 
358
                                      theme->text_width,
 
359
                                      theme->text_height - theme->line_height);
 
360
                        usplash_clear (x1, y1, x2, y2, theme->text_background);
 
361
                        xpos = x1;
 
362
                }
 
363
                
 
364
                usplash_text (xpos, y1, &input, 1,
 
365
                              theme->text_foreground, theme->text_background);
 
366
                xpos += usplash_getfontwidth (input);
 
367
        }
 
368
        inputbuf[i] = '\0';
 
369
        
 
370
        /* We wait for timeout seconds for someone to read the user input */
 
371
        for (i = 1; i != timeout + 1; i++) {
 
372
                fifo_outfd = open (USPLASH_OUTFIFO, O_WRONLY|O_NONBLOCK);
 
373
                if (fifo_outfd < 0)
 
374
                        sleep(1);
 
375
                else
 
376
                        break;
 
377
        }
 
378
        
 
379
        if (fifo_outfd < 0)
 
380
                return 1;
 
381
        
 
382
        wlen = write (fifo_outfd, inputbuf, strlen(inputbuf) + 1);
 
383
        if (wlen < 0)
 
384
                return 1;
 
385
        
 
386
        close(fifo_outfd);
 
387
        memset(inputbuf, 0, PIPE_BUF);
 
388
        return 0;
 
389
}
 
390
 
271
391
void
272
392
draw_status (const char *string, size_t len, int mode)
273
393
{
274
 
        int x1, y1, x2, y2, fg;
275
 
 
276
 
        if (mode < 0) {
277
 
                fg = theme->text_failure;
278
 
        } else if (mode > 0) {
279
 
                fg = theme->text_success;
280
 
        } else {
281
 
                fg = theme->text_foreground;
282
 
        }
283
 
 
284
 
        x2 = left_edge + theme->text_x + theme->text_width;
285
 
        y2 = top_edge + theme->text_y + theme->text_height;
286
 
 
287
 
        x1 = x2 - theme->status_width;
288
 
        y1 = y2 - theme->line_height;
289
 
 
290
 
        usplash_clear (x1, y1, x2, y2, theme->text_background);
291
 
 
292
 
        usplash_text (x1, y1, string, len, fg, theme->text_background);
293
 
}
 
394
    blocksig();
 
395
    if (theme->draw_status)
 
396
        theme->draw_status(string, len, mode);
 
397
    else {
 
398
            int x1, y1, x2, y2, fg;
 
399
 
 
400
            if (mode < 0) {
 
401
                    fg = theme->text_failure;
 
402
            } else if (mode > 0) {
 
403
                    fg = theme->text_success;
 
404
            } else {
 
405
                    fg = theme->text_foreground;
 
406
            }
 
407
 
 
408
            x2 = left_edge + theme->text_x + theme->text_width;
 
409
            y2 = top_edge + theme->text_y + theme->text_height;
 
410
 
 
411
            x1 = x2 - theme->status_width;
 
412
            y1 = y2 - theme->line_height;
 
413
 
 
414
            usplash_clear (x1, y1, x2, y2, theme->text_background);
 
415
 
 
416
            usplash_text (x1, y1, string, len, fg, theme->text_background);
 
417
    }
 
418
    unblocksig();
 
419
}
 
420
 
 
421
void
 
422
animate_step(pulsating) {
 
423
    static int pulsate_step = 0;
 
424
    static int num_steps = 37;
 
425
    int x1, y1, x2, y2;
 
426
    if (theme->animate_step)
 
427
        theme->animate_step(pulsating);
 
428
    else {
 
429
        if (pulsating) {
 
430
            clear_progressbar();
 
431
 
 
432
            if(pulsate_step < 19)
 
433
                    x1 = left_edge + theme->progressbar_x + (theme->progressbar_width/20) * pulsate_step;
 
434
            else
 
435
                    x1 = left_edge + theme->progressbar_x + (theme->progressbar_width/20) * (36-pulsate_step);
 
436
 
 
437
            y1 = top_edge + theme->progressbar_y;
 
438
 
 
439
            x2 = x1 + (theme->progressbar_width/10);
 
440
            y2 = y1 + theme->progressbar_height;
 
441
            usplash_clear (x1, y1, x2, y2, theme->progressbar_foreground);
 
442
 
 
443
            pulsate_step = (pulsate_step + 1) % num_steps;
 
444
        }
 
445
    }
 
446
}
 
447