]> git.pld-linux.org Git - packages/kernel.git/blob - fbsplash-0.9-r6-2.6.8.1.patch
- [2.4.2x, 2.6.x] don't recursively crash in die() on CHRP/PReP machines
[packages/kernel.git] / fbsplash-0.9-r6-2.6.8.1.patch
1 diff -Nru a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
2 --- a/Documentation/fb/00-INDEX 2004-08-23 11:56:23 +02:00
3 +++ b/Documentation/fb/00-INDEX 2004-08-23 11:56:23 +02:00
4 @@ -19,6 +19,8 @@
5         - info on the Matrox frame buffer driver
6  pvr2fb.txt
7         - info on the PowerVR 2 frame buffer driver
8 +splash.txt
9 +       - info on the Framebuffer Splash
10  tgafb.txt
11         - info on the TGA (DECChip 21030) frame buffer driver
12  vesafb.txt
13 diff -Nru a/Documentation/fb/splash.txt b/Documentation/fb/splash.txt
14 --- /dev/null   Wed Dec 31 16:00:00 196900
15 +++ b/Documentation/fb/splash.txt       2004-08-23 11:56:23 +02:00
16 @@ -0,0 +1,230 @@
17 +What is it?
18 +-----------
19 +
20 +The framebuffer splash is a kernel feature that allows displaying a background
21 +picture on selected consoles and switching the first console to the so-called
22 +silent mode, while booting/rebooting/shutting down the system.
23 +
24 +What do I need to get it to work?
25 +---------------------------------
26 +
27 +To get fb splash up-and-running you will have to:
28 + 1) get a copy of splashutils from (FIXME URL)
29 + 2) get some splash themes (FIXME URL)
30 + 3) build the kernel helper program
31 + 4) build your kernel with the FB_SPLASH option enabled.
32 +
33 +To get fb splash operational right after fbcon initialization is finished, you
34 +will have to include a theme and the kernel helper into your initramfs image.
35 +Please refer to splashutils documentation for instructions on how to do that.
36 +
37 +Operation modes
38 +---------------
39 +
40 +The framebuffer splash can work in two modes: verbose and silent. The first
41 +one means "console with a background image". The latter one is a concept
42 +first introduced in bootsplash. When silent mode is active, the console is
43 +switched to a graphic mode and no text is displayed. It's up to the userspace
44 +programs to display something (a progress bar for example) on the screen. 
45 +
46 +Kernel command line parameters
47 +------------------------------
48 +
49 +Framebuffer splash can be configured from the kernel command line by passing
50 +options in the following way: "splash=option1,option2".
51 +
52 +The following options are recognized:
53 +
54 +off     - do not enable fbsplash after fbcon initialization; this is
55 +          default behaviour
56 +verbose - switch fbsplash to verbose mode after fbcon is initialized
57 +silent  - switch fbsplash to silent mode after fbcon is initialized
58 +
59 +theme:<name> - use theme 'name' on the first console, default theme name
60 +               is 'default' (who'd have guessed?)
61 +
62 +Example - you want to get verbose splash with the theme 'tux' right after 
63 +fbcon is up:
64 +  splash=verbose,theme:tux
65 +
66 +The userspace helper
67 +--------------------
68 +
69 +The userspace splash helper (by default: /sbin/splash_helper) is called by the
70 +kernel whenever an important event occurs and the kernel needs some kind of
71 +job to be carried out. Important events include console switches and graphic
72 +mode switches (the kernel requests background images and config for the current 
73 +console). The splash helper must be accessible at all times. If it's not,
74 +fbsplash will be switched off automatically.
75 +
76 +It's possible to set path to the splash helper by writing it to 
77 +/proc/sys/kernel/fbsplash.
78 +
79 +*****************************************************************************
80 +
81 +The information below is mostly technical stuff. If you don't plan to develop
82 +something fbsplash-related, there's probably no need to read it.
83 +
84 +The splash protocol
85 +-------------------
86 +
87 +The splash protocol defines a communication interface between the kernel and 
88 +the userspace splash helper.
89 +
90 +The kernel side is responsible for:
91 +
92 + o rendering console text, using an image as a background (instead of a
93 +   standard solid color fbcon uses),
94 + o accepting commands from the user via ioctls on the fbsplash device,
95 + o calling the userspace helper to set things up as soon as the fb subsystem is
96 +   initialized.
97 +
98 +The userspace helper is responsible for everything else, including parsing
99 +configuration files, decompressing the image files whenever the kernel needs
100 +it, and communicating with the kernel if necessary.
101 +
102 +The splash protocol specifies how communication is done in both ways:
103 +kernel->userspace and userspace->helper.
104 +  
105 +Kernel -> Userspace
106 +-------------------
107 +
108 +The kernel communicates with the userspace helper by calling it and specifying
109 +the task that to be done in a series of arguments.
110 +
111 +The arguments follow the pattern:
112 +<splash protocol version> <command> <parameters>
113 +
114 +All commands defined in splash protocol v1 have the following parameters:
115 + virtual console
116 + framebuffer number
117 + splash mode - 'v' indicates verbose, 's' indicates silent
118 + theme
119 +
120 +Splash protocol v1 specifies the following commands:
121 +
122 +getpic
123 +------
124 + The kernel issues this command to request image data. It's up to the userspace
125 + helper to find a background image appropriate for the specified theme and the 
126 + current resolution. The userspace helper should respond by issuing the
127 + FBIOSPLASH_SETPIC ioctl.
128 +
129 +init
130 +----
131 + The kernel issues this command if either 'verbose' or 'silent' has been
132 + specified in splash= on the kernel command line. Upon receiving this command,
133 + the userspace helper should find a proper configuration file for the
134 + specified theme and the current resolution, and issue the FBIOSPLASH_SETCFG.
135 + FBIOSPLASH_SETPIC and FBIOSPLASH_SETSTATE commands.
136 +
137 + When the userspace helper is called in an early phase of the boot process
138 + (right after the initialization of fbcon), no filesystems will be mounted.
139 + The helper program should mount sysfs and then create the appropriate 
140 + framebuffer, fbsplash and tty0 devices (if they don't already exist) to get 
141 + current display settings and to be able to communicate with the kernel side.
142 +
143 + Note that the console sem is not held when the kernel calls splash_helper
144 + with the 'init' command. The splash helper should perform all ioctls with
145 + origin set to FB_SPLASH_IO_ORIG_USER.
146 +
147 +modechange
148 +----------
149 + The kernel issues this command on a mode change. The helper's response should
150 + be similar to the response to the 'init' command. Note that this time the
151 + console sem is held and all ioctls must be performed with origin set to
152 + FB_SPLASH_IO_ORIG_KERNEL.
153 +
154 +
155 +Userspace -> Kernel
156 +-------------------
157 +
158 +Userspace programs can communicate with the kernel side via ioctls on the 
159 +on the fbsplash device. These ioctls are to be used by both the userspace helper 
160 +(called only by the kernel) and userspace configuration tools (run by the users).
161 +The splash helper should set the origin field to FB_SPLASH_IO_ORIG_KERNEL when
162 +doing the appropriate ioctls. All userspace configuration tools should use
163 +FB_SPLASH_IO_ORIG_USER. Failure to set the appropriate value in the origin
164 +field when performing ioctls from the kernel helper may result in a deadlock.
165 +
166 +The framebuffer splash provides the following ioctls (all defined in linux/fb.h):
167 +
168 +FBIOSPLASH_SETMODE
169 +description: sets the global fbsplash mode
170 +argument: unsigned int; values: FB_SPLASH_MODE_VERBOSE, FB_SPLASH_MODE_SILENT
171 +
172 +FBIOSPLASH_GETMODE
173 +description: gets the global fbsplash mode 
174 +argument: unsigned int*; values as in FBIOSPLASH_SETMODE
175 +
176 +FBIOSPLASH_SETPIC
177 +description: loads a background picture for a virtual console
178 +argument: struct fb_splash_iowrapper*; data: struct fb_image*
179 +notes: 
180 +If called for consoles other than the current foreground one, the picture data 
181 +will be ignored.
182 +
183 +If the current virtual console is running in a 8-bpp mode, the cmap substruct
184 +of fb_image has to be filled appropriately: start should be set to 16 (first 16 
185 +colors are reserved for fbcon), len to a value <= 240 and red, green and blue
186 +should point to valid cmap data. The transp field is ingored. The fields dx, dy
187 +bg_color, fg_color in fb_image are ignored as well.
188 +
189 +FBIOSPLASH_SETCFG
190 +description: sets the fbsplash config for a virtual console
191 +argument: struct fb_splash_iowrapper*; data: struct vc_splash*; 
192 +          the structure has to be filled with valid data.
193 +
194 +FBIOSPLASH_GETCFG
195 +description: gets the fbsplash config for a virtual console
196 +argument: struct fb_splash_iowrapper*; data: struct vc_splash*
197 +
198 +FBIOSPLASH_SETSTATE
199 +description: sets the fbsplash state for a virtual console
200 +argument: struct fb_splash_iowrapper*; data: unsigned int*
201 +         values: 0 = disabled, 1 = enabled.
202 +
203 +FBIOSPLASH_GETSTATE
204 +description: gets the fbsplash state for a virtual console
205 +argument: struct fb_splash_iowrapper*; data: unsigned int*
206 +          values: as in FBIOSPLASH_SETSTATE
207 +
208 +Info on used structures:
209 +
210 +Definition of struct vc_splash can be found in linux/console_splash.h, it's
211 +heavily commented, so no special descriptions are necessary. Note that 
212 +the 'theme' field should point to a string no longer than FB_SPLASH_THEME_LEN.
213 +When FBIOSPLASH_GETCFG call is performed, the theme field should point to a
214 +char buffer of length FB_SPLASH_THEME_LEN.
215 +
216 +Definition of struct fb_splash_iowrapper can be found in linux/fb.h. 
217 +The fields in this struct have the following meaning:
218 +
219 +vc: 
220 +Virtual console number.
221 +
222 +origin: 
223 +Specifies if the ioctl is performed as a response to a kernel request. The
224 +splash helper should set this field to FB_SPLASH_IO_ORIG_KERNEL, userspace
225 +programs should set it to FB_SPLASH_IO_ORIG_USER. This field is necessary to
226 +avoid console semaphore deadlocks.
227 +
228 +data: 
229 +Pointer to a data structure appropriate for the performed ioctl. Type of
230 +the data struct is specified in the ioctls description, for example 'data:
231 +struct vc_splash*' means that the 'data' field should be a pointer to a
232 +vc_splash struct.
233 +
234 +*****************************************************************************
235 +
236 +Credit
237 +------
238 +
239 +Original idea & implementation by:
240 +  Volker Poplawski <volker@poplawski.de>, Stefan Reinauer <stepan@suse.de>,
241 +  Steffen Winterfeldt <snwint@suse.de>, Michael Schroeder <mls@suse.de>,
242 +  Ken Wimer <wimer@suse.de>.
243 +
244 +Splash protocol redesign, current implementation, docs by:
245 +  Michal Januszewski <spock@gentoo.org>
246 +
247 diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
248 --- a/drivers/char/keyboard.c   2004-08-23 11:56:23 +02:00
249 +++ b/drivers/char/keyboard.c   2004-08-23 11:56:23 +02:00
250 @@ -41,6 +41,8 @@
251  #include <linux/sysrq.h>
252  #include <linux/input.h>
253  
254 +#include "../video/fbsplash.h"
255 +
256  static void kbd_disconnect(struct input_handle *handle);
257  extern void ctrl_alt_del(void);
258  
259 @@ -1057,6 +1059,12 @@
260                 if (emulate_raw(vc, keycode, !down << 7))
261                         if (keycode < BTN_MISC)
262                                 printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
263 +
264 +       /* switch splash to verbose mode if ESC or F2 is pressed */
265 +       if (down == 1 && (keycode == KEY_ESC || keycode == KEY_F2)) {
266 +               if (fbsplash_verbose())
267 +                       return;
268 +       }
269  
270  #ifdef CONFIG_MAGIC_SYSRQ             /* Handle the SysRq Hack */
271         if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {
272 diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c
273 --- a/drivers/char/n_tty.c      2004-08-23 11:56:23 +02:00
274 +++ b/drivers/char/n_tty.c      2004-08-23 11:56:23 +02:00
275 @@ -49,6 +49,8 @@
276  #include <asm/system.h>
277  #include <asm/bitops.h>
278  
279 +#include "../video/fbsplash.h"
280 +
281  /* number of characters left in xmit buffer before select has we have room */
282  #define WAKEUP_CHARS 256
283  
284 @@ -987,6 +989,15 @@
285         if (!tty->read_buf) {
286                 printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
287                 return -EIO;
288 +       }
289 +
290 +       /* automatically switch splash to verbose mode if someone tries to 
291 +          read from tty0 */
292 +       if (file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,0) ||
293 +           file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,1) ||
294 +           file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,0) || 
295 +           file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,1)) {
296 +               fbsplash_verbose();
297         }
298  
299         /* Job control check -- must be done at start and after
300 diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
301 --- a/drivers/video/Kconfig     2004-08-23 11:56:23 +02:00
302 +++ b/drivers/video/Kconfig     2004-08-23 11:56:23 +02:00
303 @@ -1002,5 +1002,15 @@
304         source "drivers/video/logo/Kconfig"
305  endif
306  
307 -endmenu
308 +config FB_SPLASH
309 +       bool "Support for the framebuffer splash"
310 +       depends on FRAMEBUFFER_CONSOLE=y
311 +       default n
312 +       ---help---
313 +         This option enables support for the Linux boot-up splash screen and
314 +         graphical backgrounds on consoles. Note that you will need userspace
315 +         splashutils in order to take advantage of these features. Refer to
316 +         Documentation/fb/splash.txt for more information.
317  
318 +         If unsure, say N.
319 +endmenu
320 diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
321 --- a/drivers/video/Makefile    2004-08-23 11:56:23 +02:00
322 +++ b/drivers/video/Makefile    2004-08-23 11:56:23 +02:00
323 @@ -6,6 +6,7 @@
324  
325  obj-$(CONFIG_VT)                 += console/
326  obj-$(CONFIG_LOGO)               += logo/
327 +obj-$(CONFIG_FB_SPLASH)           += fbsplash.o cfbsplash.o
328  
329  obj-$(CONFIG_FB)                  += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
330  # Only include macmodes.o if we have FB support and are PPC
331 diff -Nru a/drivers/video/cfbsplash.c b/drivers/video/cfbsplash.c
332 --- /dev/null   Wed Dec 31 16:00:00 196900
333 +++ b/drivers/video/cfbsplash.c 2004-08-23 11:56:23 +02:00
334 @@ -0,0 +1,471 @@
335 +/*
336 + *  linux/drivers/video/cfbsplash.c -- Framebuffer splash render functions
337 + *  
338 + *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
339 + *
340 + *  Code based upon "Bootsplash" (C) 2001-2003 
341 + *       Volker Poplawski <volker@poplawski.de>,
342 + *       Stefan Reinauer <stepan@suse.de>,
343 + *       Steffen Winterfeldt <snwint@suse.de>,
344 + *       Michael Schroeder <mls@suse.de>,
345 + *       Ken Wimer <wimer@suse.de>.
346 + *
347 + *  This file is subject to the terms and conditions of the GNU General Public
348 + *  License.  See the file COPYING in the main directory of this archive for
349 + *  more details.
350 + */ 
351 +#include <linux/config.h>
352 +#include <linux/module.h>
353 +#include <linux/types.h>
354 +#include <linux/fb.h>
355 +#include <linux/vt_kern.h>
356 +#include <asm/irq.h>
357 +#include <asm/system.h>
358 +
359 +#include "console/fbcon.h"
360 +#include "fbsplash.h"
361 +
362 +#define parse_pixel(shift,bpp,type)                                            \
363 +       do {                                                                    \
364 +               if (d & (0x80 >> (shift)))                                      \
365 +                       dd2[(shift)] = fgx;                                     \
366 +               else                                                            \
367 +                       dd2[(shift)] = transparent ? *(type *)splash_src : bgx; \
368 +               splash_src += (bpp);                                            \
369 +       } while (0)                                                             \
370 +
371 +void fbsplash_renderc(struct fb_info *info, int ypos, int xpos, int height, 
372 +                     int width, u8* src, u32 fgx, u32 bgx, u8 transparent)
373 +{      
374 +       unsigned int x, y;
375 +       u32 dd;
376 +       int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
377 +       unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
378 +       u16 dd2[4];
379 +
380 +       u8* splash_src = (u8 *)(info->splash.data + d);
381 +       u8* dst = (u8 *)(info->screen_base + d);
382 +
383 +       if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
384 +               return;
385 +       
386 +       for (y = 0; y < height; y++) {
387 +               switch (info->var.bits_per_pixel) {
388 +       
389 +               case 32:
390 +                       for (x = 0; x < width; x++) {
391 +
392 +                               if ((x & 7) == 0)
393 +                                       d = *src++;
394 +                               if (d & 0x80)
395 +                                       dd = fgx;
396 +                               else
397 +                                       dd = transparent ? 
398 +                                            *(u32 *)splash_src : bgx;
399 +                               
400 +                               d <<= 1;
401 +                               splash_src += 4;
402 +                               fb_writel(dd, dst);
403 +                               dst += 4;
404 +                       }
405 +                       break;
406 +               case 24:
407 +                       for (x = 0; x < width; x++) {
408 +
409 +                               if ((x & 7) == 0)
410 +                                       d = *src++;
411 +                               if (d & 0x80)
412 +                                       dd = fgx;
413 +                               else
414 +                                       dd = transparent ? 
415 +                                            (*(u32 *)splash_src & 0xffffff) : bgx;
416 +                               
417 +                               d <<= 1;
418 +                               splash_src += 3;
419 +#ifdef __LITTLE_ENDIAN
420 +                               fb_writew(dd & 0xffff, dst);
421 +                               dst += 2;
422 +                               fb_writeb((dd >> 16), dst);
423 +#else
424 +                               fb_writew(dd >> 8, dst);
425 +                               dst += 2;
426 +                               fb_writeb(dd & 0xff, dst);
427 +#endif
428 +                               dst++;
429 +                       }
430 +                       break;
431 +               case 16:
432 +                       for (x = 0; x < width; x += 2) {
433 +                               if ((x & 7) == 0)
434 +                                       d = *src++;
435 +
436 +                               parse_pixel(0, 2, u16);
437 +                               parse_pixel(1, 2, u16);
438 +#ifdef __LITTLE_ENDIAN
439 +                               dd = dd2[0] | (dd2[1] << 16);
440 +#else
441 +                               dd = dd2[1] | (dd2[1] << 16);
442 +#endif
443 +                               d <<= 2;
444 +                               fb_writel(dd, dst);
445 +                               dst += 4;
446 +                       }
447 +                       break;
448 +
449 +               case 8:
450 +                       for (x = 0; x < width; x += 4) {
451 +                               if ((x & 7) == 0)
452 +                                       d = *src++;
453 +       
454 +                               parse_pixel(0, 1, u8);
455 +                               parse_pixel(1, 1, u8);
456 +                               parse_pixel(2, 1, u8);
457 +                               parse_pixel(3, 1, u8);
458 +               
459 +#ifdef __LITTLE_ENDIAN
460 +                               dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
461 +#else
462 +                               dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
463 +#endif
464 +                               d <<= 4;
465 +                               fb_writel(dd, dst);
466 +                               dst += 4;
467 +                       }               
468 +               }
469 +
470 +               d = info->fix.line_length - width * bytespp;
471 +               dst += d;
472 +               splash_src += d;
473 +       }
474 +}
475 +
476 +#define cc2cx(a)                                               \
477 +       ((info->fix.visual == FB_VISUAL_TRUECOLOR ||            \
478 +         info->fix.visual == FB_VISUAL_DIRECTCOLOR) ?          \
479 +        ((u32*)info->pseudo_palette)[a] : a)
480 +
481 +void fbsplash_putcs(struct vc_data *vc, struct fb_info *info,
482 +                  const unsigned short *s, int count, int yy, int xx)
483 +{
484 +       unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
485 +       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
486 +       int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
487 +       int fg_color, bg_color, transparent;
488 +       
489 +       u8 *src;
490 +       u32 bgx, fgx;
491 +
492 +       u16 c = scr_readw(s);
493 +
494 +       fg_color = attr_fgcol(fgshift, c);
495 +        bg_color = attr_bgcol(bgshift, c);
496 +       transparent = vc->vc_splash.bg_color == bg_color;
497 +
498 +       xx = xx * vc->vc_font.width + vc->vc_splash.tx;
499 +       yy = yy * vc->vc_font.height + vc->vc_splash.ty;
500 +
501 +       fgx = cc2cx(fg_color);
502 +       bgx = cc2cx(bg_color);
503 +
504 +       while (count--) {
505 +               c = scr_readw(s++);
506 +               src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
507 +                     ((vc->vc_font.width + 7) >> 3);
508 +
509 +               fbsplash_renderc(info, yy, xx, vc->vc_font.height, 
510 +                              vc->vc_font.width, src, fgx, bgx, transparent);
511 +               xx += vc->vc_font.width;
512 +       }
513 +}
514 +
515 +void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, 
516 +                  int ypos, int xpos)
517 +{
518 +       unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
519 +       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
520 +       int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
521 +       u32 bg_color = attr_bgcol(bgshift, c);
522 +       u32 fg_color = attr_fgcol(fgshift, c);
523 +       u8 *src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * 
524 +                 ((vc->vc_font.width + 7) >> 3);
525 +       xpos = xpos * vc->vc_font.width + vc->vc_splash.tx;
526 +       ypos = ypos * vc->vc_font.height + vc->vc_splash.ty;
527 +       
528 +       fbsplash_renderc(info, ypos, xpos, vc->vc_font.height, vc->vc_font.width, 
529 +                        src, cc2cx(fg_color), cc2cx(bg_color), 
530 +                        vc->vc_splash.bg_color == bg_color);
531 +}
532 +
533 +void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor)
534 +{
535 +       int i;
536 +       unsigned int dsize, s_pitch;
537 +       char *t = (char *)info->cursor.image.data;
538 +       struct vc_data* vc;     
539 +
540 +       vc = vc_cons[info->currcon].d;
541 +
542 +       if (cursor->set & FB_CUR_SETSIZE) {
543 +                info->cursor.image.height = cursor->image.height;
544 +                info->cursor.image.width = cursor->image.width;
545 +        }
546 +        if (cursor->set & FB_CUR_SETPOS) {
547 +                info->cursor.image.dx = cursor->image.dx;
548 +                info->cursor.image.dy = cursor->image.dy;
549 +        }
550 +        if (cursor->set & FB_CUR_SETHOT)
551 +                info->cursor.hot = cursor->hot;
552 +        if (cursor->set & FB_CUR_SETCMAP) {
553 +                if (cursor->image.depth == 1) {
554 +                        info->cursor.image.bg_color = cursor->image.bg_color;
555 +                        info->cursor.image.fg_color = cursor->image.fg_color;
556 +                } else {
557 +                        if (cursor->image.cmap.len)
558 +                                fb_copy_cmap(&cursor->image.cmap, 
559 +                                            &info->cursor.image.cmap);
560 +                }
561 +                info->cursor.image.depth = cursor->image.depth;
562 +        }
563 +       s_pitch = (info->cursor.image.width + 7) >> 3;
564 +        dsize = s_pitch * info->cursor.image.height;
565 +        if (info->cursor.enable) {
566 +                switch (info->cursor.rop) {
567 +                case ROP_XOR:
568 +                        for (i = 0; i < dsize; i++)
569 +                                t[i] = cursor->image.data[i] ^ info->cursor.mask[i];
570 +                        break;
571 +                case ROP_COPY:
572 +                default:
573 +                        for (i = 0; i < dsize; i++)
574 +                                t[i] = cursor->image.data[i] & info->cursor.mask[i];
575 +                        break;
576 +                }
577 +        } else if (t != cursor->image.data)
578 +                memcpy(t, cursor->image.data, dsize);
579 +       
580 +       fbsplash_renderc(info,
581 +                       info->cursor.image.dy + vc->vc_splash.ty,
582 +                       info->cursor.image.dx + vc->vc_splash.tx,
583 +                       info->cursor.image.height,
584 +                       info->cursor.image.width,
585 +                       (u8*)info->cursor.image.data,
586 +                       cc2cx(info->cursor.image.fg_color),
587 +                       cc2cx(info->cursor.image.bg_color),
588 +                       info->cursor.image.bg_color == vc->vc_splash.bg_color);
589 +}
590 +
591 +static void splashset(u8 *dst, int height, int width, int dstbytes, 
592 +                       u32 bgx, int bpp)
593 +{
594 +       int i;
595 +       
596 +       if (bpp == 8)
597 +               bgx |= bgx << 8;
598 +       if (bpp == 16 || bpp == 8)
599 +               bgx |= bgx << 16;
600 +       
601 +       while (height-- > 0) {
602 +               u8 *p = dst;
603 +               
604 +               switch (bpp) {
605 +               
606 +               case 32:
607 +                       for (i=0; i < width; i++) {
608 +                               fb_writel(bgx, p); p += 4;
609 +                       }
610 +                       break;
611 +               case 24:        
612 +                       for (i=0; i < width; i++) {
613 +#ifdef __LITTLE_ENDIAN
614 +                               fb_writew((bgx & 0xffff),(u16*)p); p += 2;
615 +                               fb_writeb((bgx >> 16),p++);
616 +#else
617 +                               fb_writew((bgx >> 8),(u16*)p); p += 2;
618 +                               fb_writeb((bgx & 0xff),p++);
619 +#endif
620 +                       }
621 +               case 16:
622 +                       for (i=0; i < width/4; i++) {
623 +                               fb_writel(bgx,p); p += 4;
624 +                               fb_writel(bgx,p); p += 4;
625 +                       }
626 +                       if (width & 2) {
627 +                               fb_writel(bgx,p); p += 4;
628 +                       }
629 +                       if (width & 1)
630 +                               fb_writew(bgx,(u16*)p);
631 +                       break;
632 +               case 8:
633 +                       for (i=0; i < width/4; i++) {
634 +                               fb_writel(bgx,p); p += 4;
635 +                       }
636 +                       
637 +                       if (width & 2) {
638 +                               fb_writew(bgx,p); p += 2;
639 +                       }
640 +                       if (width & 1)
641 +                               fb_writeb(bgx,(u8*)p);
642 +                       break;
643 +
644 +               }               
645 +               dst += dstbytes;
646 +       }
647 +}
648 +
649 +void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, 
650 +                  int bpp)
651 +{
652 +       int i;
653 +
654 +       while (height-- > 0) {
655 +               u32 *p = (u32 *)dst;
656 +               u32 *q = (u32 *)src;
657 +
658 +               switch (bpp) {
659 +       
660 +               case 32:
661 +                       for (i=0; i < width; i++)
662 +                               fb_writel(*q++, p++);
663 +                       break;  
664 +               case 24:        
665 +                       for (i=0; i < (width*3/4); i++)
666 +                               fb_writel(*q++, p++);
667 +                       if ((width*3) % 4) {
668 +                               if (width & 2) {
669 +                                       fb_writeb(*(u8*)q, (u8*)p);
670 +                               } else if (width & 1) {
671 +                                       fb_writew(*(u16*)q, (u16*)p);
672 +                                       fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2));
673 +                               }
674 +                       }
675 +                       break;
676 +               case 16:
677 +                       for (i=0; i < width/4; i++) {
678 +                               fb_writel(*q++, p++);
679 +                               fb_writel(*q++, p++);
680 +                       }
681 +                       if (width & 2)
682 +                               fb_writel(*q++, p++);
683 +                       if (width & 1)
684 +                               fb_writew(*(u16*)q, (u16*)p);
685 +                       break;
686 +               case 8:
687 +                       for (i=0; i < width/4; i++) 
688 +                               fb_writel(*q++, p++);
689 +                               
690 +                       if (width & 2) {
691 +                               fb_writew(*(u16*)q, (u16*)p); 
692 +                               q = (u32*) ((u16*)q + 1);
693 +                               p = (u32*) ((u16*)p + 1);
694 +                       }
695 +                       if (width & 1)
696 +                               fb_writeb(*(u8*)q, (u8*)p);
697 +                       break;
698 +               }
699 +
700 +               dst += linebytes;
701 +               src += linebytes;
702 +       }
703 +}
704 +
705 +static void splashfill(struct fb_info *info, int sy, int sx, int height, 
706 +                      int width) 
707 +{
708 +       int d = sy * info->fix.line_length + sx * ((info->var.bits_per_pixel + 7) >> 3);
709 +       
710 +       fbsplash_copy((u8 *)(info->screen_base + d), (u8 *)(info->splash.data + d),
711 +                   height, width, info->fix.line_length, info->var.bits_per_pixel);
712 +}
713 +
714 +void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, 
715 +                   int height, int width)
716 +{
717 +       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
718 +       int bg_color = attr_bgcol_ec(bgshift, vc);
719 +       int transparent = vc->vc_splash.bg_color == bg_color;
720 +       u8 *dst;
721 +
722 +       sy = sy * vc->vc_font.height + vc->vc_splash.ty;
723 +       sx = sx * vc->vc_font.width + vc->vc_splash.tx;
724 +       height *= vc->vc_font.height;
725 +       width *= vc->vc_font.width;
726 +
727 +       if (transparent) {
728 +               splashfill(info, sy, sx, height, width);
729 +       } else {
730 +               dst = (u8 *)(info->screen_base + sy * info->fix.line_length + 
731 +                            sx * ((info->var.bits_per_pixel + 7) >> 3));
732 +               splashset(dst, height, width, info->fix.line_length, cc2cx(bg_color), 
733 +                         info->var.bits_per_pixel);
734 +       }
735 +}
736 +
737 +void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, 
738 +                           int bottom_only)
739 +{
740 +       unsigned int tw = vc->vc_cols*vc->vc_font.width;
741 +       unsigned int th = vc->vc_rows*vc->vc_font.height;
742 +
743 +       if (!bottom_only) {
744 +               /* top margin */
745 +               splashfill(info, 0, 0, vc->vc_splash.ty, info->var.xres);
746 +               /* left margin */
747 +               splashfill(info, vc->vc_splash.ty, 0, th, vc->vc_splash.tx);
748 +               /* right margin */
749 +               splashfill(info, vc->vc_splash.ty, vc->vc_splash.tx + tw, th, 
750 +                          info->var.xres - vc->vc_splash.tx - tw);
751 +       }
752 +       splashfill(info, vc->vc_splash.ty + th, 0, 
753 +                  info->var.yres - vc->vc_splash.ty - th, info->var.xres);
754 +}
755 +
756 +void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, 
757 +                          int sx, int dx, int width)
758 +{
759 +       u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
760 +       u16 *s = d + (dx - sx);
761 +       u16 *start = d;
762 +       u16 *ls = d;
763 +       u16 *le = d + width;
764 +       u16 c;
765 +       int x = dx;
766 +       u16 attr = 1;
767 +
768 +       do {
769 +               c = scr_readw(d);
770 +               if (attr != (c & 0xff00)) {
771 +                       attr = c & 0xff00;
772 +                       if (d > start) {
773 +                               fbsplash_putcs(vc, info, start, d - start, y, x);
774 +                               x += d - start;
775 +                               start = d;
776 +                       }
777 +               }
778 +               if (s >= ls && s < le && c == scr_readw(s)) {
779 +                       if (d > start) {
780 +                               fbsplash_putcs(vc, info, start, d - start, y, x);
781 +                               x += d - start + 1;
782 +                               start = d + 1;
783 +                       } else {
784 +                               x++;
785 +                               start++;
786 +                       }
787 +               }
788 +               s++;
789 +               d++;
790 +       } while (d < le);
791 +       if (d > start)
792 +               fbsplash_putcs(vc, info, start, d - start, y, x);
793 +}
794 +
795 +void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank)
796 +{
797 +       if (blank) {
798 +               splashset((u8 *)info->screen_base, info->var.yres, info->var.xres,
799 +                         info->fix.line_length, 0, info->var.bits_per_pixel);
800 +       } else {
801 +               update_screen(vc->vc_num);
802 +               fbsplash_clear_margins(vc, info, 0);
803 +       }
804 +}
805 +
806 diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
807 --- a/drivers/video/console/fbcon.c     2004-08-23 11:56:23 +02:00
808 +++ b/drivers/video/console/fbcon.c     2004-08-23 11:56:23 +02:00
809 @@ -93,6 +93,7 @@
810  #endif
811  
812  #include "fbcon.h"
813 +#include "../fbsplash.h"
814  
815  #ifdef FBCONDEBUG
816  #  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
817 @@ -210,9 +211,14 @@
818             info->cursor.rop == ROP_COPY || !vc || !CON_IS_VISIBLE(vc)
819             || registered_fb[(int) con2fb_map[vc->vc_num]] != info)
820                 return;
821 +
822         acquire_console_sem();
823         info->cursor.enable ^= 1;
824 -       info->fbops->fb_cursor(info, &info->cursor);
825 +       if (fbsplash_active(info, vc_cons[info->currcon].d)) {
826 +               fbsplash_cursor(info, &info->cursor);
827 +       } else {
828 +               info->fbops->fb_cursor(info, &info->cursor);
829 +       }
830         release_console_sem();
831  }
832  
833 @@ -414,6 +420,14 @@
834         area.sy = sy * vc->vc_font.height;
835         area.dx = dx * vc->vc_font.width;
836         area.dy = dy * vc->vc_font.height;
837 +
838 +       if (fbsplash_active(info, vc)) {
839 +               area.sx += vc->vc_splash.tx;
840 +               area.sy += vc->vc_splash.ty;
841 +               area.dx += vc->vc_splash.tx;
842 +               area.dy += vc->vc_splash.ty;
843 +       }
844 +               
845         area.height = height * vc->vc_font.height;
846         area.width = width * vc->vc_font.width;
847  
848 @@ -426,6 +440,11 @@
849         int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
850         struct fb_fillrect region;
851  
852 +       if (fbsplash_active(info, vc)) {
853 +               fbsplash_clear(vc, info, sy, sx, height, width);
854 +               return;
855 +       }
856 +       
857         region.color = attr_bgcol_ec(bgshift, vc);
858         region.dx = sx * vc->vc_font.width;
859         region.dy = sy * vc->vc_font.height;
860 @@ -458,6 +477,11 @@
861         struct fb_image image;
862         u8 *src, *dst;
863  
864 +       if (fbsplash_active(info, vc)) {
865 +               fbsplash_putcs(vc, info, s, count, yy, xx);
866 +               return;
867 +       }
868 +
869         image.fg_color = attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8,
870                                     scr_readw(s));
871         image.bg_color = attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12,
872 @@ -526,6 +550,13 @@
873         unsigned int bs = info->var.yres - bh;
874         struct fb_fillrect region;
875  
876 +       if (fbsplash_active(info, vc)) {
877 +               if (!fbsplash_isverbose)
878 +                       return;
879 +               fbsplash_clear_margins(vc, info, bottom_only);
880 +               return;
881 +       }
882 +       
883         region.color = 0;
884         region.rop = ROP_COPY;
885  
886 @@ -622,6 +653,12 @@
887  
888         cols = info->var.xres / vc->vc_font.width;
889         rows = info->var.yres / vc->vc_font.height;
890 +
891 +       if (fbsplash_active(info, vc)) {
892 +               cols = vc->vc_splash.twidth / vc->vc_font.width;
893 +               rows = vc->vc_splash.theight / vc->vc_font.height;
894 +       }
895 +
896         vc_resize(vc->vc_num, cols, rows);
897  
898         DPRINTK("mode:   %s\n", info->fix.id);
899 @@ -718,7 +755,7 @@
900         if (info_idx == -1 || info == NULL)
901             return;
902         if (vc->vc_num != display_fg || (info->flags & FBINFO_MODULE) ||
903 -           (info->fix.type == FB_TYPE_TEXT))
904 +           (info->fix.type == FB_TYPE_TEXT) || fbsplash_active(info, vc))
905                 logo = 0;
906  
907         info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
908 @@ -948,6 +985,11 @@
909         if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
910                 return;
911  
912 +       if (fbsplash_active(info, vc)) {
913 +               fbsplash_putc(vc, info, c, ypos, xpos);
914 +               return;
915 +       }
916 +
917         image.dx = xpos * vc->vc_font.width;
918         image.dy = real_y(p, ypos) * vc->vc_font.height;
919         image.width = vc->vc_font.width;
920 @@ -1025,7 +1067,11 @@
921                 if (info->cursor.rop == ROP_XOR) {
922                         info->cursor.enable = 0;
923                         info->cursor.rop = ROP_COPY;
924 -                       info->fbops->fb_cursor(info, &cursor);
925 +                       if (fbsplash_active(info, vc)) {
926 +                               fbsplash_cursor(info, &cursor);
927 +                       } else {
928 +                               info->fbops->fb_cursor(info, &cursor);
929 +                       }
930                 }       
931                 break;
932         case CM_MOVE:
933 @@ -1101,7 +1147,11 @@
934                                 mask[i++] = 0xff;
935                 }
936                 info->cursor.rop = ROP_XOR;
937 -               info->fbops->fb_cursor(info, &cursor);
938 +               if (fbsplash_active(info, vc)) {
939 +                       fbsplash_cursor(info, &cursor);
940 +               } else {
941 +                       info->fbops->fb_cursor(info, &cursor);
942 +               }
943                 vbl_cursor_cnt = CURSOR_DRAW_DELAY;
944                 break;
945         }
946 @@ -1538,7 +1588,7 @@
947                         count = vc->vc_rows;
948                 if (softback_top)
949                         fbcon_softback_note(vc, t, count);
950 -               if (logo_shown >= 0)
951 +               if (logo_shown >= 0 || fbsplash_active(info, vc))
952                         goto redraw_up;
953                 switch (p->scrollmode) {
954                 case SCROLL_MOVE:
955 @@ -1625,6 +1675,8 @@
956         case SM_DOWN:
957                 if (count > vc->vc_rows)        /* Maximum realistic size */
958                         count = vc->vc_rows;
959 +               if (fbsplash_active(info, vc))
960 +                       goto redraw_down;
961                 switch (p->scrollmode) {
962                 case SCROLL_MOVE:
963                         accel_bmove(vc, info, t, 0, t + count, 0,
964 @@ -1767,6 +1819,13 @@
965                 }
966                 return;
967         }
968 +
969 +       if (fbsplash_active(info, vc) && sy == dy && height == 1) {
970 +               /* must use slower redraw bmove to keep background pic intact */
971 +               fbsplash_bmove_redraw(vc, info, sy, sx, dx, width);
972 +               return;
973 +       }
974 +
975         accel_bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
976                         height, width);
977  }
978 @@ -1821,7 +1880,7 @@
979         var.yres = height * fh;
980         x_diff = info->var.xres - var.xres;
981         y_diff = info->var.yres - var.yres;
982 -       if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) {
983 +       if ((x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) && !vc->vc_splash.state) {
984                 char mode[40];
985  
986                 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
987 @@ -1849,6 +1908,15 @@
988         struct display *p = &fb_display[vc->vc_num];
989         int i;
990  
991 +       if (fbsplash_active_vc(vc)) {
992 +               struct vc_data *vc_curr = vc_cons[info->currcon].d;
993 +
994 +               if (!vc_curr->vc_splash.theme || strcmp(vc->vc_splash.theme, vc_curr->vc_splash.theme)) {
995 +                       if (fbsplash_call_helper("getpic", vc->vc_num))
996 +                               fbsplash_disable(vc, 0);
997 +               }
998 +       }
999 +
1000         if (softback_top) {
1001                 int l = fbcon_softback_size / vc->vc_size_row;
1002                 if (softback_lines)
1003 @@ -1966,6 +2034,12 @@
1004         fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
1005  
1006         if (!info->fbops->fb_blank) {
1007 +               
1008 +               if (fbsplash_active(info, vc)) {
1009 +                       fbsplash_blank(vc, info, blank);
1010 +                       return 0;
1011 +               }
1012 +               
1013                 if (blank) {
1014                         unsigned short oldc;
1015                         u_int height;
1016 @@ -2134,9 +2208,16 @@
1017         }
1018  
1019         if (resize) {
1020 +               u32 xres = info->var.xres, yres = info->var.yres;
1021                 /* reset wrap/pan */
1022                 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
1023 -               vc_resize(vc->vc_num, info->var.xres / w, info->var.yres / h);
1024 +
1025 +               if (fbsplash_active(info, vc)) {
1026 +                       xres = vc->vc_splash.twidth;
1027 +                       yres = vc->vc_splash.theight;
1028 +               }
1029 +               
1030 +               vc_resize(vc->vc_num, xres / w, yres / h);
1031                 if (CON_IS_VISIBLE(vc) && softback_buf) {
1032                         int l = fbcon_softback_size / vc->vc_size_row;
1033                         if (l > 5)
1034 @@ -2310,7 +2391,63 @@
1035         else
1036                 palette_cmap.len = 16;
1037         palette_cmap.start = 0;
1038 -       return fb_set_cmap(&palette_cmap, info);
1039 +
1040 +       if (fbsplash_active(info, vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1041 +
1042 +               u16 *red, *green, *blue;
1043 +               u32 col;
1044 +               int minlen = min(min(info->var.red.length, info->var.green.length), 
1045 +                                    info->var.blue.length);
1046 +               int h;
1047 +
1048 +               struct fb_cmap cmap = {
1049 +                       .start = 0,
1050 +                       .len = (1 << minlen),
1051 +                       .red = NULL,
1052 +                       .green = NULL,
1053 +                       .blue = NULL,
1054 +                       .transp = NULL
1055 +               };
1056 +
1057 +               red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
1058 +       
1059 +               if (!red)
1060 +                       goto out;               
1061 +       
1062 +               green = red + 256;
1063 +               blue = green + 265;
1064 +               cmap.red = red;
1065 +               cmap.green = green;
1066 +               cmap.blue = blue;
1067 +               
1068 +               for (i = 0; i < cmap.len; i++) {
1069 +                       red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
1070 +               }
1071 +
1072 +               h = fb_set_cmap(&cmap, info);
1073 +
1074 +               for (j = i = 0; i < 16; i++) {
1075 +                       k = table[i];
1076 +                       
1077 +                       col = ((vc->vc_palette[j++]  >> (8-minlen)) 
1078 +                               << info->var.red.offset);
1079 +                       col |= ((vc->vc_palette[j++] >> (8-minlen)) 
1080 +                               << info->var.green.offset);
1081 +                       col |= ((vc->vc_palette[j++] >> (8-minlen)) 
1082 +                               << info->var.blue.offset);
1083 +
1084 +                       ((u32 *)info->pseudo_palette)[k] = col;
1085 +               }
1086 +
1087 +               kfree(red);
1088 +               
1089 +               return h;
1090 +               
1091 +       } else if (fbsplash_active(info, vc) && info->var.bits_per_pixel == 8 && 
1092 +                  info->splash.cmap.red != NULL) 
1093 +               fb_set_cmap(&info->splash.cmap, info);
1094 +               
1095 +out:   return fb_set_cmap(&palette_cmap, info);
1096  }
1097  
1098  static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
1099 @@ -2490,7 +2627,10 @@
1100  {
1101         /* Clear cursor, restore saved data */
1102         info->cursor.enable = 0;
1103 -       info->fbops->fb_cursor(info, &info->cursor);
1104 +       if (fbsplash_active(info, vc_cons[info->currcon].d))
1105 +               fbsplash_cursor(info, &info->cursor);
1106 +       else
1107 +               info->fbops->fb_cursor(info, &info->cursor);
1108  }
1109  
1110  static void fbcon_resumed(struct fb_info *info)
1111 @@ -2522,7 +2662,14 @@
1112         if (CON_IS_VISIBLE(vc)) {
1113                 cols = info->var.xres / vc->vc_font.width;
1114                 rows = info->var.yres / vc->vc_font.height;
1115 -               vc_resize(vc->vc_num, cols, rows);
1116 +               
1117 +               if (!fbsplash_active(info, vc)) {
1118 +                       vc_resize(vc->vc_num, cols, rows);
1119 +               } else {
1120 +                       if (fbsplash_call_helper("modechange", vc->vc_num))
1121 +                               fbsplash_disable(vc, 0);
1122 +               }
1123 +       
1124                 updatescrollmode(p, info, vc);
1125                 scrollback_max = 0;
1126                 scrollback_current = 0;
1127 @@ -2632,6 +2779,9 @@
1128                 fbcon_event_notifier_registered = 1;
1129         } 
1130         release_console_sem();
1131 +
1132 +       fbsplash_init();
1133 +
1134         return 0;
1135  }
1136  
1137 diff -Nru a/drivers/video/fbsplash.c b/drivers/video/fbsplash.c
1138 --- /dev/null   Wed Dec 31 16:00:00 196900
1139 +++ b/drivers/video/fbsplash.c  2004-08-23 11:56:23 +02:00
1140 @@ -0,0 +1,527 @@
1141 +/* 
1142 + *  linux/drivers/video/fbsplash.c -- Framebuffer splash routines
1143 + *
1144 + *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
1145 + *
1146 + *  Code based upon "Bootsplash" (C) 2001-2003 
1147 + *       Volker Poplawski <volker@poplawski.de>,
1148 + *       Stefan Reinauer <stepan@suse.de>,
1149 + *       Steffen Winterfeldt <snwint@suse.de>,
1150 + *       Michael Schroeder <mls@suse.de>,
1151 + *       Ken Wimer <wimer@suse.de>.
1152 + *
1153 + *  Splash render routines are located in /linux/drivers/video/cfbsplash.c
1154 + * 
1155 + *  This file is subject to the terms and conditions of the GNU General Public
1156 + *  License.  See the file COPYING in the main directory of this archive for
1157 + *  more details.
1158 + * 
1159 + */
1160 +#include <linux/config.h>
1161 +#include <linux/module.h>
1162 +#include <linux/kernel.h>
1163 +#include <linux/string.h>
1164 +#include <linux/types.h>
1165 +#include <linux/fb.h>
1166 +#include <linux/vt_kern.h>
1167 +#include <linux/vmalloc.h>
1168 +#include <linux/unistd.h>
1169 +#include <linux/syscalls.h>
1170 +#include <linux/init.h>
1171 +#include <linux/proc_fs.h>
1172 +#include <linux/workqueue.h>
1173 +#include <linux/kmod.h>
1174 +#include <linux/miscdevice.h>
1175 +#include <linux/device.h>
1176 +#include <linux/fs.h>
1177 +
1178 +#include <asm/uaccess.h>
1179 +#include <asm/irq.h>
1180 +#include <asm/system.h>
1181 +
1182 +#include "console/fbcon.h"
1183 +#include "fbsplash.h"
1184 +
1185 +#define SPLASH_VERSION "0.9"
1186 +
1187 +#ifdef DEBUG
1188 +#define DPRINTK(fmt, args...)  printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
1189 +#else
1190 +#define DPRINTK(fmt, args...)
1191 +#endif
1192 +
1193 +static void splash_work_verbose(void *data);
1194 +static int fbsplash_enable(struct vc_data *vc);
1195 +
1196 +DECLARE_WORK(splash_wq_verbose, splash_work_verbose, NULL);
1197 +
1198 +int fbsplash_mode = 0;
1199 +char fbsplash_path[KMOD_PATH_LEN] = "/sbin/splash_helper";
1200 +static char fbsplash_theme[FB_SPLASH_THEME_LEN] __initdata = "default";
1201 +
1202 +int fbsplash_call_helper(char* cmd, unsigned short vc)
1203 +{
1204 +       char *envp[] = {
1205 +               "HOME=/",
1206 +               "PATH=/sbin:/bin",
1207 +               NULL
1208 +       };
1209 +
1210 +       char tfb[5];
1211 +       char tcons[5];
1212 +       unsigned char fb = (int) con2fb_map[vc];
1213 +
1214 +       char *argv[] = {
1215 +               fbsplash_path,
1216 +               "1",
1217 +               cmd,
1218 +               tcons,
1219 +               tfb,
1220 +               (fbsplash_mode == FB_SPLASH_MODE_SILENT) ? "s" : "v",
1221 +               vc_cons[vc].d->vc_splash.theme,
1222 +               NULL
1223 +       };
1224 +
1225 +       snprintf(tfb,5,"%d",fb);
1226 +       snprintf(tcons,5,"%d",vc);
1227 +       
1228 +       return call_usermodehelper(fbsplash_path, argv, envp, 1);
1229 +}
1230 +
1231 +int fbsplash_verbose(void)
1232 +{
1233 +       if (fbsplash_mode == FB_SPLASH_MODE_VERBOSE)
1234 +               return 0;
1235 +
1236 +       fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1237 +       
1238 +       /* We have to do the switch from a workqueue helper, because chances are this
1239 +        * function gets called from interrupt context, and we can't get hold of the 
1240 +        * console sem this way. */
1241 +       schedule_work(&splash_wq_verbose);
1242 +
1243 +       return 1;
1244 +}
1245 +
1246 +/* Switches the first console to verbose mode. */
1247 +static void splash_work_verbose(void *data)
1248 +{
1249 +       struct fb_info *info;
1250 +       struct vc_data *vc;
1251 +       
1252 +       vc = vc_cons[0].d;
1253 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1254 +
1255 +       if (info == NULL)
1256 +               return;
1257 +
1258 +       printk(KERN_INFO "fbsplash: switching to verbose mode\n");
1259 +
1260 +       vt_cons[0]->vc_mode = KD_TEXT;
1261 +
1262 +       acquire_console_sem();
1263 +       do_unblank_screen(0);
1264 +
1265 +       if (info->splash.data) {
1266 +               fbsplash_enable(vc);
1267 +       } else {
1268 +               fbsplash_disable(vc, 1);
1269 +       }
1270 +       release_console_sem();
1271 +}
1272 +
1273 +/* Disables fbsplash on a virtual console; called with console sem held. */
1274 +int fbsplash_disable(struct vc_data *vc, unsigned char redraw)
1275 +{
1276 +       struct fb_info* info;
1277 +
1278 +       if (!vc->vc_splash.state)
1279 +               return -EINVAL;
1280 +
1281 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1282 +
1283 +       if (info == NULL)
1284 +               return -EINVAL;
1285 +
1286 +       vc->vc_splash.state = 0; 
1287 +       vc_resize(vc->vc_num, info->var.xres / vc->vc_font.width, 
1288 +                 info->var.yres / vc->vc_font.height);
1289 +
1290 +       if (fg_console == vc->vc_num && redraw) {
1291 +               redraw_screen(fg_console, 0);
1292 +               update_region(fg_console, vc->vc_origin + 
1293 +                             vc->vc_size_row * vc->vc_top, 
1294 +                             vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1295 +       }
1296 +
1297 +       printk(KERN_INFO "fbsplash: switched splash state to 'off' on console %d\n", 
1298 +                        vc->vc_num);
1299 +
1300 +       return 0;
1301 +}
1302 +
1303 +/* Enables fbsplash on a virtual console; called with console sem held. */
1304 +static int fbsplash_enable(struct vc_data *vc)
1305 +{
1306 +       struct fb_info* info;
1307 +
1308 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1309 +               
1310 +       if (vc->vc_splash.twidth == 0 || vc->vc_splash.theight == 0 || 
1311 +           info == NULL || !info->splash.data || vc->vc_splash.state)
1312 +               return -EINVAL;
1313 +       
1314 +       vc->vc_splash.state = 1;
1315 +       vc_resize(vc->vc_num, vc->vc_splash.twidth / vc->vc_font.width, 
1316 +                 vc->vc_splash.theight / vc->vc_font.height);
1317 +
1318 +       if (fg_console == vc->vc_num) {
1319 +               redraw_screen(fg_console, 0);
1320 +               update_region(fg_console, vc->vc_origin + 
1321 +                             vc->vc_size_row * vc->vc_top, 
1322 +                             vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1323 +               fbsplash_clear_margins(vc, info, 0);
1324 +       }
1325 +
1326 +       printk(KERN_INFO "fbsplash: switched splash state to 'on' on console %d\n", 
1327 +                        vc->vc_num);
1328 +
1329 +       return 0;
1330 +}
1331 +
1332 +static int __init splash_setup(char *options)
1333 +{
1334 +       char *this_opt;
1335 +       
1336 +       while ((this_opt = strsep(&options, ",")) != NULL) {
1337 +       
1338 +               if (!strcmp(this_opt, "silent")) {
1339 +                       fbsplash_mode = FB_SPLASH_MODE_SILENT;
1340 +                       printk(KERN_INFO "fbsplash: silent\n");
1341 +               } else if (!strcmp(this_opt, "verbose")) {
1342 +                       fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1343 +                       printk(KERN_INFO "fbsplash: verbose\n");
1344 +               } else if (!strcmp(this_opt, "off")) {
1345 +                       fbsplash_mode = 0;
1346 +               } else if (!strncmp(this_opt, "theme:", 6)) {
1347 +                       strncpy(fbsplash_theme, this_opt+6, 64);
1348 +                       printk(KERN_INFO "fbsplash: theme %s\n", fbsplash_theme);
1349 +               } else {
1350 +                       printk(KERN_WARNING "fbsplash: unrecognized option %s\n", this_opt);
1351 +               }
1352 +       }
1353 +       return 0;
1354 +}
1355 +
1356 +__setup("splash=", splash_setup);
1357 +
1358 +static int splash_get_info(char *buf, char **start, off_t fpos, int length)
1359 +{
1360 +       char *p = buf;
1361 +       
1362 +       p += sprintf(p, "Framebuffer splash v%s, mode: %s\n", SPLASH_VERSION,
1363 +                    ((fbsplash_mode == 2) ? "silent" : (fbsplash_mode == 1) ? "verbose" : "off"));
1364 +
1365 +       return p - buf;
1366 +}
1367 +
1368 +static inline int fbsplash_ioctl_dosetstate(struct vc_data *vc, unsigned int __user* state, unsigned char origin)
1369 +{
1370 +       int tmp, ret;
1371 +
1372 +       if (get_user(tmp, state))
1373 +               return -EFAULT;
1374 +
1375 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1376 +               acquire_console_sem();
1377 +       if (!tmp)
1378 +               ret = fbsplash_disable(vc, 1);
1379 +       else
1380 +               ret = fbsplash_enable(vc);
1381 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1382 +               release_console_sem();
1383 +
1384 +       return ret;
1385 +}
1386 +
1387 +static inline int fbsplash_ioctl_dogetstate(struct vc_data *vc, unsigned int __user *state)
1388 +{
1389 +       return put_user(vc->vc_splash.state, (unsigned int __user*) state);
1390 +}
1391 +
1392 +static int fbsplash_ioctl_dosetcfg(struct vc_data *vc, struct vc_splash __user *arg, unsigned char origin)
1393 +{
1394 +       struct vc_splash cfg;
1395 +       struct fb_info *info;
1396 +       int len;
1397 +       char *tmp;
1398 +       
1399 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1400 +
1401 +       if (copy_from_user(&cfg, arg, sizeof(struct vc_splash)))
1402 +               return -EFAULT;
1403 +       if (info == NULL || !cfg.twidth || !cfg.theight || 
1404 +           cfg.tx + cfg.twidth  > info->var.xres ||
1405 +           cfg.ty + cfg.theight > info->var.yres)
1406 +               return -EINVAL;
1407 +
1408 +       len = strlen_user(cfg.theme);
1409 +       if (!len || len > FB_SPLASH_THEME_LEN)
1410 +               return -EINVAL;
1411 +       tmp = kmalloc(len, GFP_KERNEL);
1412 +       if (!tmp)
1413 +               return -ENOMEM;
1414 +       if (copy_from_user(tmp, (void __user *)cfg.theme, len))
1415 +               return -EFAULT;
1416 +       cfg.theme = tmp;
1417 +       cfg.state = 0;
1418 +
1419 +       /* If this ioctl is a response to a request from kernel, the console sem
1420 +        * is already held; we also don't need to disable splash because either the
1421 +        * new config and background picture will be successfully loaded, and the 
1422 +        * splash will stay on, or in case of a failure it'll be turned off in fbcon. */
1423 +       if (origin == FB_SPLASH_IO_ORIG_USER) {
1424 +               acquire_console_sem();
1425 +               if (vc->vc_splash.state)
1426 +                       fbsplash_disable(vc, 1);
1427 +       }
1428 +
1429 +       if (vc->vc_splash.theme)
1430 +               kfree(vc->vc_splash.theme);
1431 +
1432 +       vc->vc_splash = cfg;
1433 +
1434 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1435 +               release_console_sem();
1436 +
1437 +       printk(KERN_INFO "fbsplash: console %d using theme '%s'\n", 
1438 +                        vc->vc_num, vc->vc_splash.theme);
1439 +       return 0;       
1440 +}
1441 +
1442 +static int fbsplash_ioctl_dogetcfg(struct vc_data *vc, struct vc_splash __user *arg)
1443 +{
1444 +       struct vc_splash splash;
1445 +       char __user *tmp;
1446 +
1447 +       if (get_user(tmp, &arg->theme))
1448 +               return -EFAULT;
1449 +       
1450 +       splash = vc->vc_splash;
1451 +       splash.theme = tmp;
1452 +
1453 +       if (vc->vc_splash.theme) {
1454 +               if (copy_to_user(tmp, vc->vc_splash.theme, strlen(vc->vc_splash.theme) + 1))
1455 +                       return -EFAULT;
1456 +       } else
1457 +               if (put_user(0, tmp))
1458 +                       return -EFAULT;
1459 +
1460 +       if (copy_to_user(arg, &splash, sizeof(struct vc_splash)))
1461 +               return -EFAULT;
1462 +
1463 +       return 0;
1464 +}
1465 +
1466 +static int fbsplash_ioctl_dosetpic(struct vc_data *vc, struct fb_image __user *arg, unsigned char origin)
1467 +{
1468 +       struct fb_image img;
1469 +       struct fb_info *info;
1470 +       int len;
1471 +       u8 *tmp;
1472 +       
1473 +       if (vc->vc_num != fg_console) 
1474 +               return -EINVAL;
1475 +
1476 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1477 +       
1478 +       if (info == NULL)
1479 +               return -EINVAL;
1480 +       
1481 +       if (copy_from_user(&img, arg, sizeof(struct fb_image)))
1482 +               return -EFAULT;
1483 +       
1484 +       if (img.width != info->var.xres || img.height != info->var.yres) {
1485 +               printk(KERN_ERR "fbsplash: picture dimensions mismatch\n");
1486 +               return -EINVAL;
1487 +       }
1488 +
1489 +       if (img.depth != info->var.bits_per_pixel) {
1490 +               printk(KERN_ERR "fbsplash: picture depth mismatch\n");
1491 +               return -EINVAL;
1492 +       }
1493 +               
1494 +       if (img.depth == 8) {
1495 +               if (!img.cmap.len || !img.cmap.red || !img.cmap.green || 
1496 +                   !img.cmap.blue)
1497 +                       return -EINVAL;
1498 +               
1499 +               tmp = vmalloc(img.cmap.len * 3 * 2);
1500 +               if (!tmp)
1501 +                       return -ENOMEM;
1502 +
1503 +               if (copy_from_user(tmp, (void __user*)img.cmap.red, img.cmap.len * 2) ||
1504 +                   copy_from_user(tmp + (img.cmap.len << 1),
1505 +                                  (void __user*)img.cmap.green, (img.cmap.len << 1)) ||
1506 +                   copy_from_user(tmp + (img.cmap.len << 2),
1507 +                                  (void __user*)img.cmap.blue, (img.cmap.len << 1))) {
1508 +                       vfree(tmp);
1509 +                       return -EFAULT;
1510 +               }
1511 +                       
1512 +               img.cmap.transp = NULL;
1513 +               img.cmap.red = (u16*)tmp;
1514 +               img.cmap.green = img.cmap.red + img.cmap.len;
1515 +               img.cmap.blue = img.cmap.green + img.cmap.len;
1516 +       } else {
1517 +               img.cmap.red = NULL;
1518 +       }
1519 +               
1520 +       len = ((img.depth + 7) >> 3) * img.width * img.height;
1521 +       tmp = vmalloc(len);
1522 +
1523 +       if (!tmp)
1524 +               goto out;
1525 +
1526 +       if (copy_from_user(tmp, (void __user*)img.data, len))
1527 +               goto out;
1528 +               
1529 +       img.data = tmp;
1530 +
1531 +       /* If this ioctl is a response to a request from kernel, the console sem
1532 +        * is already held. */
1533 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1534 +               acquire_console_sem();
1535 +       
1536 +       if (info->splash.data)
1537 +               vfree((u8*)info->splash.data);
1538 +       if (info->splash.cmap.red)
1539 +               vfree(info->splash.cmap.red);
1540 +       
1541 +       info->splash = img;
1542 +
1543 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1544 +               release_console_sem();
1545 +
1546 +       return 0;
1547 +
1548 +out:   if (img.cmap.red)
1549 +               vfree(img.cmap.red);
1550 +       if (tmp)
1551 +               vfree(tmp);
1552 +       return -ENOMEM;
1553 +}
1554 +
1555 +static int splash_ioctl(struct inode * inode, struct file *filp, u_int cmd, 
1556 +                       u_long arg)
1557 +{
1558 +       struct fb_splash_iowrapper __user *wrapper = (void __user*) arg;
1559 +       struct vc_data *vc = NULL;
1560 +       unsigned short vc_num = 0;
1561 +       unsigned char origin = 0;
1562 +       void __user *data = NULL;
1563 +       
1564 +       if (cmd != FBIOSPLASH_SETMODE && cmd != FBIOSPLASH_GETMODE)
1565 +       {
1566 +               if (verify_area(VERIFY_READ, wrapper, 
1567 +                               sizeof(struct fb_splash_iowrapper)))
1568 +                       return -EFAULT;
1569 +       
1570 +               __get_user(vc_num, &wrapper->vc);
1571 +               __get_user(origin, &wrapper->origin);
1572 +               __get_user(data, &wrapper->data);
1573 +               
1574 +               if (!vc_cons_allocated(vc_num))
1575 +                       return -EINVAL;
1576 +
1577 +               vc = vc_cons[vc_num].d;
1578 +       }
1579 +       
1580 +       switch (cmd) {
1581 +       
1582 +       case FBIOSPLASH_SETMODE:
1583 +               if (arg != FB_SPLASH_MODE_SILENT && arg != FB_SPLASH_MODE_VERBOSE)
1584 +                       return -EINVAL;
1585 +       
1586 +               if (fbsplash_mode == arg)
1587 +                       return 0;
1588 +       
1589 +               fbsplash_mode = arg;
1590 +               if (arg == FB_SPLASH_MODE_VERBOSE)
1591 +                       splash_work_verbose(NULL);
1592 +               return 0;
1593 +       
1594 +       case FBIOSPLASH_GETMODE:
1595 +               return put_user(fbsplash_mode, (unsigned int __user *)arg);
1596 +       case FBIOSPLASH_SETPIC:
1597 +               return fbsplash_ioctl_dosetpic(vc, (struct fb_image __user*)data, origin);
1598 +       case FBIOSPLASH_SETCFG:
1599 +               return fbsplash_ioctl_dosetcfg(vc, (struct vc_splash*)data, origin);
1600 +       case FBIOSPLASH_GETCFG:
1601 +               return fbsplash_ioctl_dogetcfg(vc, (struct vc_splash*)data);
1602 +       case FBIOSPLASH_SETSTATE:
1603 +               return fbsplash_ioctl_dosetstate(vc, (unsigned int *)data, origin);
1604 +       case FBIOSPLASH_GETSTATE:
1605 +               return fbsplash_ioctl_dogetstate(vc, (unsigned int *)data);
1606 +       default:
1607 +               return -ENOIOCTLCMD;
1608 +       }       
1609 +}
1610 +
1611 +static struct file_operations splash_ops = {
1612 +       .owner = THIS_MODULE,
1613 +       .ioctl = splash_ioctl
1614 +};
1615 +
1616 +static struct miscdevice splash_dev = {
1617 +       .minor = MISC_DYNAMIC_MINOR,
1618 +       .name = "fbsplash",
1619 +       .fops = &splash_ops
1620 +};
1621 +
1622 +int fbsplash_init(void)
1623 +{
1624 +       struct proc_dir_entry *splash_proc;
1625 +       struct fb_info *info;
1626 +       struct vc_data *vc;
1627 +       int i;
1628 +       
1629 +       vc = vc_cons[0].d;
1630 +       info = registered_fb[0];
1631 +
1632 +       for (i = 0; i < num_registered_fb; i++) {
1633 +               registered_fb[i]->splash.data = NULL;
1634 +               registered_fb[i]->splash.cmap.red = NULL;
1635 +       }
1636 +
1637 +       for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
1638 +               vc_cons[i].d->vc_splash.state = vc_cons[i].d->vc_splash.twidth = 
1639 +                                               vc_cons[i].d->vc_splash.theight = 0;
1640 +               vc_cons[i].d->vc_splash.theme = NULL;
1641 +       }
1642 +
1643 +       i = misc_register(&splash_dev);
1644 +       if (i) {
1645 +               printk(KERN_ERR "fbsplash: failed to register device\n");
1646 +               return i;
1647 +       }
1648 +
1649 +#ifdef CONFIG_PROC_FS
1650 +       splash_proc = create_proc_info_entry("fbsplash", 0, NULL, splash_get_info);
1651 +       if (splash_proc)
1652 +               splash_proc->owner = THIS_MODULE;
1653 +#endif
1654 +       
1655 +       if (fbsplash_mode && info) {
1656 +               vc->vc_splash.theme = kmalloc((strlen(fbsplash_theme)+1) * sizeof(char), GFP_KERNEL);
1657 +               strcpy(vc->vc_splash.theme, fbsplash_theme);
1658 +               if (fbsplash_call_helper("init", 0))
1659 +                       fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1660 +       } else {
1661 +               fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1662 +       }
1663 +               
1664 +       return 0;
1665 +}
1666 +
1667 +EXPORT_SYMBOL(fbsplash_path);
1668 diff -Nru a/drivers/video/fbsplash.h b/drivers/video/fbsplash.h
1669 --- /dev/null   Wed Dec 31 16:00:00 196900
1670 +++ b/drivers/video/fbsplash.h  2004-08-23 11:56:23 +02:00
1671 @@ -0,0 +1,69 @@
1672 +/* 
1673 + *  linux/drivers/video/fbsplash.h -- Framebuffer splash headers
1674 + *
1675 + *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
1676 + *
1677 + */
1678 +
1679 +#ifndef __FB_SPLASH_H
1680 +#define __FB_SPLASH_H
1681 +
1682 +struct fb_cursor;
1683 +struct fb_info;
1684 +struct vc_data;
1685 +
1686 +#ifdef CONFIG_FB_SPLASH
1687 +/* fbsplash.c */
1688 +int fbsplash_init(void);
1689 +int fbsplash_verbose(void);
1690 +int fbsplash_call_helper(char* cmd, unsigned short cons);
1691 +int fbsplash_disable(struct vc_data *vc, unsigned char redraw);
1692 +
1693 +/* cfbsplash.c */
1694 +void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
1695 +void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos);
1696 +void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor);
1697 +void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
1698 +void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
1699 +void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank);
1700 +void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
1701 +void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int bpp);
1702 +
1703 +/* vt.c */
1704 +void acquire_console_sem(void);
1705 +void release_console_sem(void);
1706 +void do_unblank_screen(int entering_gfx);
1707 +
1708 +extern int fbsplash_mode;
1709 +#define fbsplash_isverbose (fbsplash_mode == FB_SPLASH_MODE_VERBOSE)
1710 +
1711 +/* struct vc_data *y */
1712 +#define fbsplash_active_vc(y) (y->vc_splash.state && y->vc_splash.theme) 
1713 +
1714 +/* struct fb_info *x, struct vc_data *y */
1715 +#define fbsplash_active(x,y) (x->splash.data && fbsplash_active_vc(y) &&               \
1716 +                             x->splash.width == x->var.xres &&                         \
1717 +                             x->splash.height == x->var.yres &&                        \
1718 +                             x->splash.depth == x->var.bits_per_pixel)
1719 +
1720 +#else /* CONFIG_FB_SPLASH */
1721 +
1722 +static inline void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
1723 +static inline void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
1724 +static inline void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
1725 +static inline void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
1726 +static inline void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
1727 +static inline void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
1728 +static inline void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
1729 +static inline int fbsplash_call_helper(char* cmd, unsigned short cons) { return 0; }
1730 +static inline int fbsplash_init(void) { return 0; }
1731 +static inline int fbsplash_verbose(void) { return 0; }
1732 +static inline int fbsplash_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
1733 +
1734 +#define fbsplash_isverbose (0)
1735 +#define fbsplash_active_vc(y) (0)
1736 +#define fbsplash_active(x,y) (0)
1737 +
1738 +#endif /* CONFIG_FB_SPLASH */
1739 +
1740 +#endif /* __FB_SPLASH_H */
1741 diff -Nru a/include/linux/console_splash.h b/include/linux/console_splash.h
1742 --- /dev/null   Wed Dec 31 16:00:00 196900
1743 +++ b/include/linux/console_splash.h    2004-08-23 11:56:23 +02:00
1744 @@ -0,0 +1,13 @@
1745 +#ifndef _LINUX_CONSOLE_SPLASH_H_
1746 +#define _LINUX_CONSOLE_SPLASH_H_ 1
1747 +
1748 +/* A structure used by the framebuffer splash code (drivers/video/fbsplash.c) */
1749 +struct vc_splash {
1750 +       __u8 bg_color;                          /* The color that is to be treated as transparent */
1751 +       __u8 state;                             /* Current splash state: 0 = off, 1 = on */
1752 +       __u16 tx, ty;                           /* Top left corner coordinates of the text field */
1753 +       __u16 twidth, theight;                  /* Width and height of the text field */
1754 +       char* theme;
1755 +};
1756 +
1757 +#endif
1758 diff -Nru a/include/linux/console_struct.h b/include/linux/console_struct.h
1759 --- a/include/linux/console_struct.h    2004-08-23 11:56:23 +02:00
1760 +++ b/include/linux/console_struct.h    2004-08-23 11:56:23 +02:00
1761 @@ -10,6 +10,7 @@
1762   */
1763  
1764  #define NPAR 16
1765 +#include <linux/console_splash.h>
1766  
1767  struct vc_data {
1768         unsigned short  vc_num;                 /* Console number */
1769 @@ -87,6 +88,8 @@
1770         struct vc_data **vc_display_fg;         /* [!] Ptr to var holding fg console for this display */
1771         unsigned long   vc_uni_pagedir;
1772         unsigned long   *vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
1773 +
1774 +       struct vc_splash vc_splash;
1775         /* additional information is in vt_kern.h */
1776  };
1777  
1778 diff -Nru a/include/linux/fb.h b/include/linux/fb.h
1779 --- a/include/linux/fb.h        2004-08-23 11:56:23 +02:00
1780 +++ b/include/linux/fb.h        2004-08-23 11:56:23 +02:00
1781 @@ -8,6 +8,13 @@
1782  #define FB_MAJOR               29
1783  #define FB_MAX                 32      /* sufficient for now */
1784  
1785 +struct fb_splash_iowrapper
1786 +{
1787 +       unsigned short vc;              /* Virtual console */
1788 +       unsigned char origin;           /* Point of origin of the request */
1789 +       void *data;
1790 +};
1791 +
1792  /* ioctls
1793     0x46 is 'F'                                                         */
1794  #define FBIOGET_VSCREENINFO    0x4600
1795 @@ -35,7 +42,19 @@
1796  #define FBIOGET_HWCINFO         0x4616
1797  #define FBIOPUT_MODEINFO        0x4617
1798  #define FBIOGET_DISPINFO        0x4618
1799 -
1800 +#define FBIOSPLASH_SETCFG      _IOWR('F', 0x19, struct fb_splash_iowrapper)
1801 +#define FBIOSPLASH_GETCFG      _IOR('F', 0x1A, struct fb_splash_iowrapper)
1802 +#define FBIOSPLASH_SETSTATE    _IOWR('F', 0x1B, struct fb_splash_iowrapper)
1803 +#define FBIOSPLASH_GETSTATE    _IOR('F', 0x1C, struct fb_splash_iowrapper)
1804 +#define FBIOSPLASH_SETMODE     _IOWR('F', 0x1D, unsigned int)
1805 +#define FBIOSPLASH_GETMODE     _IOR('F', 0x1E, unsigned int)
1806 +#define FBIOSPLASH_SETPIC      _IOWR('F', 0x1F, struct fb_splash_iowrapper)
1807 +
1808 +#define FB_SPLASH_MODE_VERBOSE         1       /* Verbose mode */
1809 +#define FB_SPLASH_MODE_SILENT          2       /* Silent mode */
1810 +#define FB_SPLASH_THEME_LEN            128     /* Maximum lenght of a theme name */
1811 +#define FB_SPLASH_IO_ORIG_KERNEL       0       /* Kernel ioctl origin */
1812 +#define FB_SPLASH_IO_ORIG_USER         1       /* User ioctl origin */
1813  
1814  #define FB_TYPE_PACKED_PIXELS          0       /* Packed Pixels        */
1815  #define FB_TYPE_PLANES                 1       /* Non interleaved planes */
1816 @@ -588,6 +607,8 @@
1817  #define FBINFO_STATE_RUNNING   0
1818  #define FBINFO_STATE_SUSPENDED 1
1819         u32 state;                      /* Hardware state i.e suspend */
1820 +
1821 +       struct fb_image splash;
1822  
1823         /* From here on everything is device dependent */
1824         void *par;      
1825 diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
1826 --- a/include/linux/sysctl.h    2004-08-23 11:56:23 +02:00
1827 +++ b/include/linux/sysctl.h    2004-08-23 11:56:23 +02:00
1828 @@ -133,6 +133,7 @@
1829         KERN_NGROUPS_MAX=63,    /* int: NGROUPS_MAX */
1830         KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
1831         KERN_HZ_TIMER=65,       /* int: hz timer on or off */
1832 +       KERN_FBSPLASH=66,       /* string: path to fbsplash helper */
1833  };
1834  
1835  
1836 diff -Nru a/kernel/panic.c b/kernel/panic.c
1837 --- a/kernel/panic.c    2004-08-23 11:56:23 +02:00
1838 +++ b/kernel/panic.c    2004-08-23 11:56:23 +02:00
1839 @@ -19,6 +19,7 @@
1840  #include <linux/syscalls.h>
1841  #include <linux/interrupt.h>
1842  #include <linux/nmi.h>
1843 +#include "../drivers/video/fbsplash.h"
1844  
1845  int panic_timeout;
1846  int panic_on_oops;
1847 @@ -82,6 +83,8 @@
1848                  * We can't use the "normal" timers since we just panicked..
1849                  */
1850                 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
1851 +               fbsplash_verbose();
1852 +               
1853                 for (i = 0; i < panic_timeout; i++) {
1854                         touch_nmi_watchdog();
1855                         mdelay(1000);
1856 @@ -105,6 +108,8 @@
1857          disabled_wait(caller);
1858  #endif
1859         local_irq_enable();
1860 +       fbsplash_verbose();
1861 +
1862         for (;;)
1863                 ;
1864  }
1865 diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
1866 --- a/kernel/sysctl.c   2004-08-23 11:56:23 +02:00
1867 +++ b/kernel/sysctl.c   2004-08-23 11:56:23 +02:00
1868 @@ -77,6 +77,9 @@
1869  #ifdef CONFIG_HOTPLUG
1870  extern char hotplug_path[];
1871  #endif
1872 +#ifdef CONFIG_FB_SPLASH
1873 +extern char fbsplash_path[];
1874 +#endif
1875  #ifdef CONFIG_CHR_DEV_SG
1876  extern int sg_big_buff;
1877  #endif
1878 @@ -403,6 +406,17 @@
1879                 .ctl_name       = KERN_HOTPLUG,
1880                 .procname       = "hotplug",
1881                 .data           = &hotplug_path,
1882 +               .maxlen         = KMOD_PATH_LEN,
1883 +               .mode           = 0644,
1884 +               .proc_handler   = &proc_dostring,
1885 +               .strategy       = &sysctl_string,
1886 +       },
1887 +#endif
1888 +#ifdef CONFIG_FB_SPLASH
1889 +       {
1890 +               .ctl_name       = KERN_FBSPLASH,
1891 +               .procname       = "fbsplash",
1892 +               .data           = &fbsplash_path,
1893                 .maxlen         = KMOD_PATH_LEN,
1894                 .mode           = 0644,
1895                 .proc_handler   = &proc_dostring,
This page took 0.184417 seconds and 3 git commands to generate.