]> git.pld-linux.org Git - packages/kernel.git/blob - fbsplash-0.9-r7-2.6.9-rc1.patch
- now on HEAD
[packages/kernel.git] / fbsplash-0.9-r7-2.6.9-rc1.patch
1 diff -Nru a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
2 --- a/Documentation/fb/00-INDEX 2004-08-26 21:34:52 +02:00
3 +++ b/Documentation/fb/00-INDEX 2004-08-26 21:34:52 +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-26 21:34:52 +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-26 21:34:52 +02:00
249 +++ b/drivers/char/keyboard.c   2004-08-26 21:34:52 +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-26 21:34:52 +02:00
274 +++ b/drivers/char/n_tty.c      2004-08-26 21:34:52 +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-26 21:34:52 +02:00
302 +++ b/drivers/video/Kconfig     2004-08-26 21:34:52 +02:00
303 @@ -1011,5 +1011,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-26 21:34:52 +02:00
322 +++ b/drivers/video/Makefile    2004-08-26 21:34:52 +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-26 21:34:52 +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-26 21:34:52 +02:00
808 +++ b/drivers/video/console/fbcon.c     2004-08-26 21:34:52 +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 @@ -516,6 +522,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 @@ -528,6 +542,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 @@ -561,6 +580,11 @@
861         struct fb_image image;
862         u8 *src, *dst, *buf = NULL;
863  
864 +       if (fbsplash_active(info, vc)) {
865 +               fbsplash_putcs(vc, info, s, count, yy, xx);
866 +               return;
867 +       }
868 +
869         if (attribute) {
870                 buf = kmalloc(cellsize, GFP_KERNEL);
871                 if (!buf)
872 @@ -648,6 +672,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 @@ -785,6 +816,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 @@ -881,7 +918,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 @@ -1166,7 +1203,11 @@
909                 if (info->cursor.rop == ROP_XOR) {
910                         info->cursor.enable = 0;
911                         info->cursor.rop = ROP_COPY;
912 -                       info->fbops->fb_cursor(info, &cursor);
913 +                       if (fbsplash_active(info, vc)) {
914 +                               fbsplash_cursor(info, &cursor);
915 +                       } else {
916 +                               info->fbops->fb_cursor(info, &cursor);
917 +                       }
918                 }       
919                 break;
920         case CM_MOVE:
921 @@ -1246,7 +1287,11 @@
922                                 mask[i++] = msk;
923                 }
924                 info->cursor.rop = ROP_XOR;
925 -               info->fbops->fb_cursor(info, &cursor);
926 +               if (fbsplash_active(info, vc)) {
927 +                       fbsplash_cursor(info, &cursor);
928 +               } else {
929 +                       info->fbops->fb_cursor(info, &cursor);
930 +               }
931                 vbl_cursor_cnt = CURSOR_DRAW_DELAY;
932                 break;
933         }
934 @@ -1685,7 +1730,7 @@
935                         count = vc->vc_rows;
936                 if (softback_top)
937                         fbcon_softback_note(vc, t, count);
938 -               if (logo_shown >= 0)
939 +               if (logo_shown >= 0 || fbsplash_active(info, vc))
940                         goto redraw_up;
941                 switch (p->scrollmode) {
942                 case SCROLL_MOVE:
943 @@ -1772,6 +1817,8 @@
944         case SM_DOWN:
945                 if (count > vc->vc_rows)        /* Maximum realistic size */
946                         count = vc->vc_rows;
947 +               if (fbsplash_active(info, vc))
948 +                       goto redraw_down;
949                 switch (p->scrollmode) {
950                 case SCROLL_MOVE:
951                         accel_bmove(vc, info, t, 0, t + count, 0,
952 @@ -1914,6 +1961,13 @@
953                 }
954                 return;
955         }
956 +
957 +       if (fbsplash_active(info, vc) && sy == dy && height == 1) {
958 +               /* must use slower redraw bmove to keep background pic intact */
959 +               fbsplash_bmove_redraw(vc, info, sy, sx, dx, width);
960 +               return;
961 +       }
962 +
963         accel_bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
964                         height, width);
965  }
966 @@ -1968,7 +2022,8 @@
967         var.yres = height * fh;
968         x_diff = info->var.xres - var.xres;
969         y_diff = info->var.yres - var.yres;
970 -       if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) {
971 +
972 +       if ((x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) && !vc->vc_splash.state) {
973                 struct fb_videomode *mode;
974  
975                 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
976 @@ -2014,6 +2069,15 @@
977         struct fb_var_screeninfo var;
978         int i;
979  
980 +       if (fbsplash_active_vc(vc)) {
981 +               struct vc_data *vc_curr = vc_cons[info->currcon].d;
982 +
983 +               if (!vc_curr->vc_splash.theme || strcmp(vc->vc_splash.theme, vc_curr->vc_splash.theme)) {
984 +                       if (fbsplash_call_helper("getpic", vc->vc_num))
985 +                               fbsplash_disable(vc, 0);
986 +               }
987 +       }
988 +
989         if (softback_top) {
990                 int l = fbcon_softback_size / vc->vc_size_row;
991                 if (softback_lines)
992 @@ -2144,6 +2208,12 @@
993         fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
994  
995         if (!info->fbops->fb_blank) {
996 +               
997 +               if (fbsplash_active(info, vc)) {
998 +                       fbsplash_blank(vc, info, blank);
999 +                       return 0;
1000 +               }
1001 +               
1002                 if (blank) {
1003                         unsigned short oldc;
1004                         u_int height;
1005 @@ -2312,9 +2382,16 @@
1006         }
1007  
1008         if (resize) {
1009 +               u32 xres = info->var.xres, yres = info->var.yres;
1010                 /* reset wrap/pan */
1011                 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
1012 -               vc_resize(vc->vc_num, info->var.xres / w, info->var.yres / h);
1013 +
1014 +               if (fbsplash_active(info, vc)) {
1015 +                       xres = vc->vc_splash.twidth;
1016 +                       yres = vc->vc_splash.theight;
1017 +               }
1018 +               
1019 +               vc_resize(vc->vc_num, xres / w, yres / h);
1020                 if (CON_IS_VISIBLE(vc) && softback_buf) {
1021                         int l = fbcon_softback_size / vc->vc_size_row;
1022                         if (l > 5)
1023 @@ -2493,7 +2570,62 @@
1024         } else
1025                 fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
1026  
1027 -       return fb_set_cmap(&palette_cmap, info);
1028 +       if (fbsplash_active(info, vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1029 +
1030 +               u16 *red, *green, *blue;
1031 +               u32 col;
1032 +               int minlen = min(min(info->var.red.length, info->var.green.length), 
1033 +                                    info->var.blue.length);
1034 +               int h;
1035 +
1036 +               struct fb_cmap cmap = {
1037 +                       .start = 0,
1038 +                       .len = (1 << minlen),
1039 +                       .red = NULL,
1040 +                       .green = NULL,
1041 +                       .blue = NULL,
1042 +                       .transp = NULL
1043 +               };
1044 +
1045 +               red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
1046 +       
1047 +               if (!red)
1048 +                       goto out;               
1049 +       
1050 +               green = red + 256;
1051 +               blue = green + 265;
1052 +               cmap.red = red;
1053 +               cmap.green = green;
1054 +               cmap.blue = blue;
1055 +               
1056 +               for (i = 0; i < cmap.len; i++) {
1057 +                       red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
1058 +               }
1059 +
1060 +               h = fb_set_cmap(&cmap, info);
1061 +
1062 +               for (j = i = 0; i < 16; i++) {
1063 +                       k = table[i];
1064 +                       
1065 +                       col = ((vc->vc_palette[j++]  >> (8-minlen)) 
1066 +                               << info->var.red.offset);
1067 +                       col |= ((vc->vc_palette[j++] >> (8-minlen)) 
1068 +                               << info->var.green.offset);
1069 +                       col |= ((vc->vc_palette[j++] >> (8-minlen)) 
1070 +                               << info->var.blue.offset);
1071 +
1072 +                       ((u32 *)info->pseudo_palette)[k] = col;
1073 +               }
1074 +
1075 +               kfree(red);
1076 +               
1077 +               return h;
1078 +               
1079 +       } else if (fbsplash_active(info, vc) && info->var.bits_per_pixel == 8 && 
1080 +                  info->splash.cmap.red != NULL) 
1081 +               fb_set_cmap(&info->splash.cmap, info);
1082 +               
1083 +out:   return fb_set_cmap(&palette_cmap, info);
1084  }
1085  
1086  static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
1087 @@ -2673,7 +2805,10 @@
1088  {
1089         /* Clear cursor, restore saved data */
1090         info->cursor.enable = 0;
1091 -       info->fbops->fb_cursor(info, &info->cursor);
1092 +       if (fbsplash_active(info, vc_cons[info->currcon].d))
1093 +               fbsplash_cursor(info, &info->cursor);
1094 +       else
1095 +               info->fbops->fb_cursor(info, &info->cursor);
1096  }
1097  
1098  static void fbcon_resumed(struct fb_info *info)
1099 @@ -2704,7 +2839,14 @@
1100                 var_to_display(p, &info->var, info);
1101                 cols = info->var.xres / vc->vc_font.width;
1102                 rows = info->var.yres / vc->vc_font.height;
1103 -               vc_resize(vc->vc_num, cols, rows);
1104 +               
1105 +               if (!fbsplash_active(info, vc)) {
1106 +                       vc_resize(vc->vc_num, cols, rows);
1107 +               } else {
1108 +                       if (fbsplash_call_helper("modechange", vc->vc_num))
1109 +                               fbsplash_disable(vc, 0);
1110 +               }
1111 +       
1112                 updatescrollmode(p, info, vc);
1113                 scrollback_max = 0;
1114                 scrollback_current = 0;
1115 @@ -2842,6 +2984,7 @@
1116         acquire_console_sem();
1117         fb_register_client(&fbcon_event_notifier);
1118         release_console_sem();
1119 +       fbsplash_init();
1120  
1121         for (i = 0; i < MAX_NR_CONSOLES; i++)
1122                 con2fb_map[i] = -1;
1123 diff -Nru a/drivers/video/fbsplash.c b/drivers/video/fbsplash.c
1124 --- /dev/null   Wed Dec 31 16:00:00 196900
1125 +++ b/drivers/video/fbsplash.c  2004-08-26 21:34:52 +02:00
1126 @@ -0,0 +1,527 @@
1127 +/* 
1128 + *  linux/drivers/video/fbsplash.c -- Framebuffer splash routines
1129 + *
1130 + *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
1131 + *
1132 + *  Code based upon "Bootsplash" (C) 2001-2003 
1133 + *       Volker Poplawski <volker@poplawski.de>,
1134 + *       Stefan Reinauer <stepan@suse.de>,
1135 + *       Steffen Winterfeldt <snwint@suse.de>,
1136 + *       Michael Schroeder <mls@suse.de>,
1137 + *       Ken Wimer <wimer@suse.de>.
1138 + *
1139 + *  Splash render routines are located in /linux/drivers/video/cfbsplash.c
1140 + * 
1141 + *  This file is subject to the terms and conditions of the GNU General Public
1142 + *  License.  See the file COPYING in the main directory of this archive for
1143 + *  more details.
1144 + * 
1145 + */
1146 +#include <linux/config.h>
1147 +#include <linux/module.h>
1148 +#include <linux/kernel.h>
1149 +#include <linux/string.h>
1150 +#include <linux/types.h>
1151 +#include <linux/fb.h>
1152 +#include <linux/vt_kern.h>
1153 +#include <linux/vmalloc.h>
1154 +#include <linux/unistd.h>
1155 +#include <linux/syscalls.h>
1156 +#include <linux/init.h>
1157 +#include <linux/proc_fs.h>
1158 +#include <linux/workqueue.h>
1159 +#include <linux/kmod.h>
1160 +#include <linux/miscdevice.h>
1161 +#include <linux/device.h>
1162 +#include <linux/fs.h>
1163 +
1164 +#include <asm/uaccess.h>
1165 +#include <asm/irq.h>
1166 +#include <asm/system.h>
1167 +
1168 +#include "console/fbcon.h"
1169 +#include "fbsplash.h"
1170 +
1171 +#define SPLASH_VERSION "0.9"
1172 +
1173 +#ifdef DEBUG
1174 +#define DPRINTK(fmt, args...)  printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
1175 +#else
1176 +#define DPRINTK(fmt, args...)
1177 +#endif
1178 +
1179 +static void splash_work_verbose(void *data);
1180 +static int fbsplash_enable(struct vc_data *vc);
1181 +
1182 +DECLARE_WORK(splash_wq_verbose, splash_work_verbose, NULL);
1183 +
1184 +int fbsplash_mode = 0;
1185 +char fbsplash_path[KMOD_PATH_LEN] = "/sbin/splash_helper";
1186 +static char fbsplash_theme[FB_SPLASH_THEME_LEN] __initdata = "default";
1187 +
1188 +int fbsplash_call_helper(char* cmd, unsigned short vc)
1189 +{
1190 +       char *envp[] = {
1191 +               "HOME=/",
1192 +               "PATH=/sbin:/bin",
1193 +               NULL
1194 +       };
1195 +
1196 +       char tfb[5];
1197 +       char tcons[5];
1198 +       unsigned char fb = (int) con2fb_map[vc];
1199 +
1200 +       char *argv[] = {
1201 +               fbsplash_path,
1202 +               "1",
1203 +               cmd,
1204 +               tcons,
1205 +               tfb,
1206 +               (fbsplash_mode == FB_SPLASH_MODE_SILENT) ? "s" : "v",
1207 +               vc_cons[vc].d->vc_splash.theme,
1208 +               NULL
1209 +       };
1210 +
1211 +       snprintf(tfb,5,"%d",fb);
1212 +       snprintf(tcons,5,"%d",vc);
1213 +       
1214 +       return call_usermodehelper(fbsplash_path, argv, envp, 1);
1215 +}
1216 +
1217 +int fbsplash_verbose(void)
1218 +{
1219 +       if (fbsplash_mode == FB_SPLASH_MODE_VERBOSE)
1220 +               return 0;
1221 +
1222 +       fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1223 +       
1224 +       /* We have to do the switch from a workqueue helper, because chances are this
1225 +        * function gets called from interrupt context, and we can't get hold of the 
1226 +        * console sem this way. */
1227 +       schedule_work(&splash_wq_verbose);
1228 +
1229 +       return 1;
1230 +}
1231 +
1232 +/* Switches the first console to verbose mode. */
1233 +static void splash_work_verbose(void *data)
1234 +{
1235 +       struct fb_info *info;
1236 +       struct vc_data *vc;
1237 +       
1238 +       vc = vc_cons[0].d;
1239 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1240 +
1241 +       if (info == NULL)
1242 +               return;
1243 +
1244 +       printk(KERN_INFO "fbsplash: switching to verbose mode\n");
1245 +
1246 +       vt_cons[0]->vc_mode = KD_TEXT;
1247 +
1248 +       acquire_console_sem();
1249 +       do_unblank_screen(0);
1250 +
1251 +       if (info->splash.data) {
1252 +               fbsplash_enable(vc);
1253 +       } else {
1254 +               fbsplash_disable(vc, 1);
1255 +       }
1256 +       release_console_sem();
1257 +}
1258 +
1259 +/* Disables fbsplash on a virtual console; called with console sem held. */
1260 +int fbsplash_disable(struct vc_data *vc, unsigned char redraw)
1261 +{
1262 +       struct fb_info* info;
1263 +
1264 +       if (!vc->vc_splash.state)
1265 +               return -EINVAL;
1266 +
1267 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1268 +
1269 +       if (info == NULL)
1270 +               return -EINVAL;
1271 +
1272 +       vc->vc_splash.state = 0; 
1273 +       vc_resize(vc->vc_num, info->var.xres / vc->vc_font.width, 
1274 +                 info->var.yres / vc->vc_font.height);
1275 +
1276 +       if (fg_console == vc->vc_num && redraw) {
1277 +               redraw_screen(fg_console, 0);
1278 +               update_region(fg_console, vc->vc_origin + 
1279 +                             vc->vc_size_row * vc->vc_top, 
1280 +                             vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1281 +       }
1282 +
1283 +       printk(KERN_INFO "fbsplash: switched splash state to 'off' on console %d\n", 
1284 +                        vc->vc_num);
1285 +
1286 +       return 0;
1287 +}
1288 +
1289 +/* Enables fbsplash on a virtual console; called with console sem held. */
1290 +static int fbsplash_enable(struct vc_data *vc)
1291 +{
1292 +       struct fb_info* info;
1293 +
1294 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1295 +               
1296 +       if (vc->vc_splash.twidth == 0 || vc->vc_splash.theight == 0 || 
1297 +           info == NULL || !info->splash.data || vc->vc_splash.state)
1298 +               return -EINVAL;
1299 +       
1300 +       vc->vc_splash.state = 1;
1301 +       vc_resize(vc->vc_num, vc->vc_splash.twidth / vc->vc_font.width, 
1302 +                 vc->vc_splash.theight / vc->vc_font.height);
1303 +
1304 +       if (fg_console == vc->vc_num) {
1305 +               redraw_screen(fg_console, 0);
1306 +               update_region(fg_console, vc->vc_origin + 
1307 +                             vc->vc_size_row * vc->vc_top, 
1308 +                             vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1309 +               fbsplash_clear_margins(vc, info, 0);
1310 +       }
1311 +
1312 +       printk(KERN_INFO "fbsplash: switched splash state to 'on' on console %d\n", 
1313 +                        vc->vc_num);
1314 +
1315 +       return 0;
1316 +}
1317 +
1318 +static int __init splash_setup(char *options)
1319 +{
1320 +       char *this_opt;
1321 +       
1322 +       while ((this_opt = strsep(&options, ",")) != NULL) {
1323 +       
1324 +               if (!strcmp(this_opt, "silent")) {
1325 +                       fbsplash_mode = FB_SPLASH_MODE_SILENT;
1326 +                       printk(KERN_INFO "fbsplash: silent\n");
1327 +               } else if (!strcmp(this_opt, "verbose")) {
1328 +                       fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1329 +                       printk(KERN_INFO "fbsplash: verbose\n");
1330 +               } else if (!strcmp(this_opt, "off")) {
1331 +                       fbsplash_mode = 0;
1332 +               } else if (!strncmp(this_opt, "theme:", 6)) {
1333 +                       strncpy(fbsplash_theme, this_opt+6, 64);
1334 +                       printk(KERN_INFO "fbsplash: theme %s\n", fbsplash_theme);
1335 +               } else {
1336 +                       printk(KERN_WARNING "fbsplash: unrecognized option %s\n", this_opt);
1337 +               }
1338 +       }
1339 +       return 0;
1340 +}
1341 +
1342 +__setup("splash=", splash_setup);
1343 +
1344 +static int splash_get_info(char *buf, char **start, off_t fpos, int length)
1345 +{
1346 +       char *p = buf;
1347 +       
1348 +       p += sprintf(p, "Framebuffer splash v%s, mode: %s\n", SPLASH_VERSION,
1349 +                    ((fbsplash_mode == 2) ? "silent" : (fbsplash_mode == 1) ? "verbose" : "off"));
1350 +
1351 +       return p - buf;
1352 +}
1353 +
1354 +static inline int fbsplash_ioctl_dosetstate(struct vc_data *vc, unsigned int __user* state, unsigned char origin)
1355 +{
1356 +       int tmp, ret;
1357 +
1358 +       if (get_user(tmp, state))
1359 +               return -EFAULT;
1360 +
1361 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1362 +               acquire_console_sem();
1363 +       if (!tmp)
1364 +               ret = fbsplash_disable(vc, 1);
1365 +       else
1366 +               ret = fbsplash_enable(vc);
1367 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1368 +               release_console_sem();
1369 +
1370 +       return ret;
1371 +}
1372 +
1373 +static inline int fbsplash_ioctl_dogetstate(struct vc_data *vc, unsigned int __user *state)
1374 +{
1375 +       return put_user(vc->vc_splash.state, (unsigned int __user*) state);
1376 +}
1377 +
1378 +static int fbsplash_ioctl_dosetcfg(struct vc_data *vc, struct vc_splash __user *arg, unsigned char origin)
1379 +{
1380 +       struct vc_splash cfg;
1381 +       struct fb_info *info;
1382 +       int len;
1383 +       char *tmp;
1384 +       
1385 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1386 +
1387 +       if (copy_from_user(&cfg, arg, sizeof(struct vc_splash)))
1388 +               return -EFAULT;
1389 +       if (info == NULL || !cfg.twidth || !cfg.theight || 
1390 +           cfg.tx + cfg.twidth  > info->var.xres ||
1391 +           cfg.ty + cfg.theight > info->var.yres)
1392 +               return -EINVAL;
1393 +
1394 +       len = strlen_user(cfg.theme);
1395 +       if (!len || len > FB_SPLASH_THEME_LEN)
1396 +               return -EINVAL;
1397 +       tmp = kmalloc(len, GFP_KERNEL);
1398 +       if (!tmp)
1399 +               return -ENOMEM;
1400 +       if (copy_from_user(tmp, (void __user *)cfg.theme, len))
1401 +               return -EFAULT;
1402 +       cfg.theme = tmp;
1403 +       cfg.state = 0;
1404 +
1405 +       /* If this ioctl is a response to a request from kernel, the console sem
1406 +        * is already held; we also don't need to disable splash because either the
1407 +        * new config and background picture will be successfully loaded, and the 
1408 +        * splash will stay on, or in case of a failure it'll be turned off in fbcon. */
1409 +       if (origin == FB_SPLASH_IO_ORIG_USER) {
1410 +               acquire_console_sem();
1411 +               if (vc->vc_splash.state)
1412 +                       fbsplash_disable(vc, 1);
1413 +       }
1414 +
1415 +       if (vc->vc_splash.theme)
1416 +               kfree(vc->vc_splash.theme);
1417 +
1418 +       vc->vc_splash = cfg;
1419 +
1420 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1421 +               release_console_sem();
1422 +
1423 +       printk(KERN_INFO "fbsplash: console %d using theme '%s'\n", 
1424 +                        vc->vc_num, vc->vc_splash.theme);
1425 +       return 0;       
1426 +}
1427 +
1428 +static int fbsplash_ioctl_dogetcfg(struct vc_data *vc, struct vc_splash __user *arg)
1429 +{
1430 +       struct vc_splash splash;
1431 +       char __user *tmp;
1432 +
1433 +       if (get_user(tmp, &arg->theme))
1434 +               return -EFAULT;
1435 +       
1436 +       splash = vc->vc_splash;
1437 +       splash.theme = tmp;
1438 +
1439 +       if (vc->vc_splash.theme) {
1440 +               if (copy_to_user(tmp, vc->vc_splash.theme, strlen(vc->vc_splash.theme) + 1))
1441 +                       return -EFAULT;
1442 +       } else
1443 +               if (put_user(0, tmp))
1444 +                       return -EFAULT;
1445 +
1446 +       if (copy_to_user(arg, &splash, sizeof(struct vc_splash)))
1447 +               return -EFAULT;
1448 +
1449 +       return 0;
1450 +}
1451 +
1452 +static int fbsplash_ioctl_dosetpic(struct vc_data *vc, struct fb_image __user *arg, unsigned char origin)
1453 +{
1454 +       struct fb_image img;
1455 +       struct fb_info *info;
1456 +       int len;
1457 +       u8 *tmp;
1458 +       
1459 +       if (vc->vc_num != fg_console) 
1460 +               return -EINVAL;
1461 +
1462 +       info = registered_fb[(int) con2fb_map[vc->vc_num]];
1463 +       
1464 +       if (info == NULL)
1465 +               return -EINVAL;
1466 +       
1467 +       if (copy_from_user(&img, arg, sizeof(struct fb_image)))
1468 +               return -EFAULT;
1469 +       
1470 +       if (img.width != info->var.xres || img.height != info->var.yres) {
1471 +               printk(KERN_ERR "fbsplash: picture dimensions mismatch\n");
1472 +               return -EINVAL;
1473 +       }
1474 +
1475 +       if (img.depth != info->var.bits_per_pixel) {
1476 +               printk(KERN_ERR "fbsplash: picture depth mismatch\n");
1477 +               return -EINVAL;
1478 +       }
1479 +               
1480 +       if (img.depth == 8) {
1481 +               if (!img.cmap.len || !img.cmap.red || !img.cmap.green || 
1482 +                   !img.cmap.blue)
1483 +                       return -EINVAL;
1484 +               
1485 +               tmp = vmalloc(img.cmap.len * 3 * 2);
1486 +               if (!tmp)
1487 +                       return -ENOMEM;
1488 +
1489 +               if (copy_from_user(tmp, (void __user*)img.cmap.red, img.cmap.len * 2) ||
1490 +                   copy_from_user(tmp + (img.cmap.len << 1),
1491 +                                  (void __user*)img.cmap.green, (img.cmap.len << 1)) ||
1492 +                   copy_from_user(tmp + (img.cmap.len << 2),
1493 +                                  (void __user*)img.cmap.blue, (img.cmap.len << 1))) {
1494 +                       vfree(tmp);
1495 +                       return -EFAULT;
1496 +               }
1497 +                       
1498 +               img.cmap.transp = NULL;
1499 +               img.cmap.red = (u16*)tmp;
1500 +               img.cmap.green = img.cmap.red + img.cmap.len;
1501 +               img.cmap.blue = img.cmap.green + img.cmap.len;
1502 +       } else {
1503 +               img.cmap.red = NULL;
1504 +       }
1505 +               
1506 +       len = ((img.depth + 7) >> 3) * img.width * img.height;
1507 +       tmp = vmalloc(len);
1508 +
1509 +       if (!tmp)
1510 +               goto out;
1511 +
1512 +       if (copy_from_user(tmp, (void __user*)img.data, len))
1513 +               goto out;
1514 +               
1515 +       img.data = tmp;
1516 +
1517 +       /* If this ioctl is a response to a request from kernel, the console sem
1518 +        * is already held. */
1519 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1520 +               acquire_console_sem();
1521 +       
1522 +       if (info->splash.data)
1523 +               vfree((u8*)info->splash.data);
1524 +       if (info->splash.cmap.red)
1525 +               vfree(info->splash.cmap.red);
1526 +       
1527 +       info->splash = img;
1528 +
1529 +       if (origin == FB_SPLASH_IO_ORIG_USER)
1530 +               release_console_sem();
1531 +
1532 +       return 0;
1533 +
1534 +out:   if (img.cmap.red)
1535 +               vfree(img.cmap.red);
1536 +       if (tmp)
1537 +               vfree(tmp);
1538 +       return -ENOMEM;
1539 +}
1540 +
1541 +static int splash_ioctl(struct inode * inode, struct file *filp, u_int cmd, 
1542 +                       u_long arg)
1543 +{
1544 +       struct fb_splash_iowrapper __user *wrapper = (void __user*) arg;
1545 +       struct vc_data *vc = NULL;
1546 +       unsigned short vc_num = 0;
1547 +       unsigned char origin = 0;
1548 +       void __user *data = NULL;
1549 +       
1550 +       if (cmd != FBIOSPLASH_SETMODE && cmd != FBIOSPLASH_GETMODE)
1551 +       {
1552 +               if (verify_area(VERIFY_READ, wrapper, 
1553 +                               sizeof(struct fb_splash_iowrapper)))
1554 +                       return -EFAULT;
1555 +       
1556 +               __get_user(vc_num, &wrapper->vc);
1557 +               __get_user(origin, &wrapper->origin);
1558 +               __get_user(data, &wrapper->data);
1559 +               
1560 +               if (!vc_cons_allocated(vc_num))
1561 +                       return -EINVAL;
1562 +
1563 +               vc = vc_cons[vc_num].d;
1564 +       }
1565 +       
1566 +       switch (cmd) {
1567 +       
1568 +       case FBIOSPLASH_SETMODE:
1569 +               if (arg != FB_SPLASH_MODE_SILENT && arg != FB_SPLASH_MODE_VERBOSE)
1570 +                       return -EINVAL;
1571 +       
1572 +               if (fbsplash_mode == arg)
1573 +                       return 0;
1574 +       
1575 +               fbsplash_mode = arg;
1576 +               if (arg == FB_SPLASH_MODE_VERBOSE)
1577 +                       splash_work_verbose(NULL);
1578 +               return 0;
1579 +       
1580 +       case FBIOSPLASH_GETMODE:
1581 +               return put_user(fbsplash_mode, (unsigned int __user *)arg);
1582 +       case FBIOSPLASH_SETPIC:
1583 +               return fbsplash_ioctl_dosetpic(vc, (struct fb_image __user*)data, origin);
1584 +       case FBIOSPLASH_SETCFG:
1585 +               return fbsplash_ioctl_dosetcfg(vc, (struct vc_splash*)data, origin);
1586 +       case FBIOSPLASH_GETCFG:
1587 +               return fbsplash_ioctl_dogetcfg(vc, (struct vc_splash*)data);
1588 +       case FBIOSPLASH_SETSTATE:
1589 +               return fbsplash_ioctl_dosetstate(vc, (unsigned int *)data, origin);
1590 +       case FBIOSPLASH_GETSTATE:
1591 +               return fbsplash_ioctl_dogetstate(vc, (unsigned int *)data);
1592 +       default:
1593 +               return -ENOIOCTLCMD;
1594 +       }       
1595 +}
1596 +
1597 +static struct file_operations splash_ops = {
1598 +       .owner = THIS_MODULE,
1599 +       .ioctl = splash_ioctl
1600 +};
1601 +
1602 +static struct miscdevice splash_dev = {
1603 +       .minor = MISC_DYNAMIC_MINOR,
1604 +       .name = "fbsplash",
1605 +       .fops = &splash_ops
1606 +};
1607 +
1608 +int fbsplash_init(void)
1609 +{
1610 +       struct proc_dir_entry *splash_proc;
1611 +       struct fb_info *info;
1612 +       struct vc_data *vc;
1613 +       int i;
1614 +       
1615 +       vc = vc_cons[0].d;
1616 +       info = registered_fb[0];
1617 +
1618 +       for (i = 0; i < num_registered_fb; i++) {
1619 +               registered_fb[i]->splash.data = NULL;
1620 +               registered_fb[i]->splash.cmap.red = NULL;
1621 +       }
1622 +
1623 +       for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
1624 +               vc_cons[i].d->vc_splash.state = vc_cons[i].d->vc_splash.twidth = 
1625 +                                               vc_cons[i].d->vc_splash.theight = 0;
1626 +               vc_cons[i].d->vc_splash.theme = NULL;
1627 +       }
1628 +
1629 +       i = misc_register(&splash_dev);
1630 +       if (i) {
1631 +               printk(KERN_ERR "fbsplash: failed to register device\n");
1632 +               return i;
1633 +       }
1634 +
1635 +#ifdef CONFIG_PROC_FS
1636 +       splash_proc = create_proc_info_entry("fbsplash", 0, NULL, splash_get_info);
1637 +       if (splash_proc)
1638 +               splash_proc->owner = THIS_MODULE;
1639 +#endif
1640 +       
1641 +       if (fbsplash_mode && info) {
1642 +               vc->vc_splash.theme = kmalloc((strlen(fbsplash_theme)+1) * sizeof(char), GFP_KERNEL);
1643 +               strcpy(vc->vc_splash.theme, fbsplash_theme);
1644 +               if (fbsplash_call_helper("init", 0))
1645 +                       fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1646 +       } else {
1647 +               fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1648 +       }
1649 +               
1650 +       return 0;
1651 +}
1652 +
1653 +EXPORT_SYMBOL(fbsplash_path);
1654 diff -Nru a/drivers/video/fbsplash.h b/drivers/video/fbsplash.h
1655 --- /dev/null   Wed Dec 31 16:00:00 196900
1656 +++ b/drivers/video/fbsplash.h  2004-08-26 21:34:52 +02:00
1657 @@ -0,0 +1,75 @@
1658 +/* 
1659 + *  linux/drivers/video/fbsplash.h -- Framebuffer splash headers
1660 + *
1661 + *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
1662 + *
1663 + */
1664 +
1665 +#ifndef __FB_SPLASH_H
1666 +#define __FB_SPLASH_H
1667 +
1668 +#ifndef _LINUX_FB_H
1669 +#include <linux/fb.h>
1670 +#endif
1671 +
1672 +struct fb_cursor;
1673 +struct fb_info;
1674 +struct vc_data;
1675 +
1676 +#ifdef CONFIG_FB_SPLASH
1677 +/* fbsplash.c */
1678 +int fbsplash_init(void);
1679 +int fbsplash_verbose(void);
1680 +int fbsplash_call_helper(char* cmd, unsigned short cons);
1681 +int fbsplash_disable(struct vc_data *vc, unsigned char redraw);
1682 +
1683 +/* cfbsplash.c */
1684 +void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
1685 +void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos);
1686 +void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor);
1687 +void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
1688 +void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
1689 +void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank);
1690 +void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
1691 +void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int bpp);
1692 +
1693 +/* vt.c */
1694 +void acquire_console_sem(void);
1695 +void release_console_sem(void);
1696 +void do_unblank_screen(int entering_gfx);
1697 +
1698 +extern int fbsplash_mode;
1699 +#define fbsplash_isverbose (fbsplash_mode == FB_SPLASH_MODE_VERBOSE)
1700 +#define fbsplash_issilent  (fbsplash_mode == FB_SPLASH_MODE_SILENT)
1701 +
1702 +/* struct vc_data *y */
1703 +#define fbsplash_active_vc(y) (y->vc_splash.state && y->vc_splash.theme) 
1704 +
1705 +/* struct fb_info *x, struct vc_data *y */
1706 +#define fbsplash_active(x,y) (x->splash.data && fbsplash_active_vc(y) &&               \
1707 +                             x->splash.width == x->var.xres &&                         \
1708 +                             x->splash.height == x->var.yres &&                        \
1709 +                             x->splash.depth == x->var.bits_per_pixel)
1710 +
1711 +#else /* CONFIG_FB_SPLASH */
1712 +
1713 +static inline void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
1714 +static inline void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
1715 +static inline void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
1716 +static inline void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
1717 +static inline void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
1718 +static inline void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
1719 +static inline void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
1720 +static inline int fbsplash_call_helper(char* cmd, unsigned short cons) { return 0; }
1721 +static inline int fbsplash_init(void) { return 0; }
1722 +static inline int fbsplash_verbose(void) { return 0; }
1723 +static inline int fbsplash_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
1724 +
1725 +#define fbsplash_issilent (0)
1726 +#define fbsplash_isverbose (1)
1727 +#define fbsplash_active_vc(y) (0)
1728 +#define fbsplash_active(x,y) (0)
1729 +
1730 +#endif /* CONFIG_FB_SPLASH */
1731 +
1732 +#endif /* __FB_SPLASH_H */
1733 diff -Nru a/include/linux/console_splash.h b/include/linux/console_splash.h
1734 --- /dev/null   Wed Dec 31 16:00:00 196900
1735 +++ b/include/linux/console_splash.h    2004-08-26 21:34:52 +02:00
1736 @@ -0,0 +1,13 @@
1737 +#ifndef _LINUX_CONSOLE_SPLASH_H_
1738 +#define _LINUX_CONSOLE_SPLASH_H_ 1
1739 +
1740 +/* A structure used by the framebuffer splash code (drivers/video/fbsplash.c) */
1741 +struct vc_splash {
1742 +       __u8 bg_color;                          /* The color that is to be treated as transparent */
1743 +       __u8 state;                             /* Current splash state: 0 = off, 1 = on */
1744 +       __u16 tx, ty;                           /* Top left corner coordinates of the text field */
1745 +       __u16 twidth, theight;                  /* Width and height of the text field */
1746 +       char* theme;
1747 +};
1748 +
1749 +#endif
1750 diff -Nru a/include/linux/console_struct.h b/include/linux/console_struct.h
1751 --- a/include/linux/console_struct.h    2004-08-26 21:34:52 +02:00
1752 +++ b/include/linux/console_struct.h    2004-08-26 21:34:52 +02:00
1753 @@ -10,6 +10,7 @@
1754   */
1755  
1756  #define NPAR 16
1757 +#include <linux/console_splash.h>
1758  
1759  struct vc_data {
1760         unsigned short  vc_num;                 /* Console number */
1761 @@ -87,6 +88,8 @@
1762         struct vc_data **vc_display_fg;         /* [!] Ptr to var holding fg console for this display */
1763         unsigned long   vc_uni_pagedir;
1764         unsigned long   *vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
1765 +
1766 +       struct vc_splash vc_splash;
1767         /* additional information is in vt_kern.h */
1768  };
1769  
1770 diff -Nru a/include/linux/fb.h b/include/linux/fb.h
1771 --- a/include/linux/fb.h        2004-08-26 21:34:52 +02:00
1772 +++ b/include/linux/fb.h        2004-08-26 21:34:52 +02:00
1773 @@ -9,6 +9,13 @@
1774  #define FB_MAJOR               29
1775  #define FB_MAX                 32      /* sufficient for now */
1776  
1777 +struct fb_splash_iowrapper
1778 +{
1779 +       unsigned short vc;              /* Virtual console */
1780 +       unsigned char origin;           /* Point of origin of the request */
1781 +       void *data;
1782 +};
1783 +
1784  /* ioctls
1785     0x46 is 'F'                                                         */
1786  #define FBIOGET_VSCREENINFO    0x4600
1787 @@ -36,7 +43,19 @@
1788  #define FBIOGET_HWCINFO         0x4616
1789  #define FBIOPUT_MODEINFO        0x4617
1790  #define FBIOGET_DISPINFO        0x4618
1791 -
1792 +#define FBIOSPLASH_SETCFG      _IOWR('F', 0x19, struct fb_splash_iowrapper)
1793 +#define FBIOSPLASH_GETCFG      _IOR('F', 0x1A, struct fb_splash_iowrapper)
1794 +#define FBIOSPLASH_SETSTATE    _IOWR('F', 0x1B, struct fb_splash_iowrapper)
1795 +#define FBIOSPLASH_GETSTATE    _IOR('F', 0x1C, struct fb_splash_iowrapper)
1796 +#define FBIOSPLASH_SETMODE     _IOWR('F', 0x1D, unsigned int)
1797 +#define FBIOSPLASH_GETMODE     _IOR('F', 0x1E, unsigned int)
1798 +#define FBIOSPLASH_SETPIC      _IOWR('F', 0x1F, struct fb_splash_iowrapper)
1799 +
1800 +#define FB_SPLASH_MODE_VERBOSE         1       /* Verbose mode */
1801 +#define FB_SPLASH_MODE_SILENT          2       /* Silent mode */
1802 +#define FB_SPLASH_THEME_LEN            128     /* Maximum lenght of a theme name */
1803 +#define FB_SPLASH_IO_ORIG_KERNEL       0       /* Kernel ioctl origin */
1804 +#define FB_SPLASH_IO_ORIG_USER         1       /* User ioctl origin */
1805  
1806  #define FB_TYPE_PACKED_PIXELS          0       /* Packed Pixels        */
1807  #define FB_TYPE_PLANES                 1       /* Non interleaved planes */
1808 @@ -601,6 +620,8 @@
1809  #define FBINFO_STATE_RUNNING   0
1810  #define FBINFO_STATE_SUSPENDED 1
1811         u32 state;                      /* Hardware state i.e suspend */
1812 +
1813 +       struct fb_image splash;
1814  
1815         /* From here on everything is device dependent */
1816         void *par;      
1817 diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
1818 --- a/include/linux/sysctl.h    2004-08-26 21:34:52 +02:00
1819 +++ b/include/linux/sysctl.h    2004-08-26 21:34:52 +02:00
1820 @@ -134,6 +134,7 @@
1821         KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
1822         KERN_HZ_TIMER=65,       /* int: hz timer on or off */
1823         KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */
1824 +       KERN_FBSPLASH=67,       /* string: path to fbsplash helper */
1825  };
1826  
1827  
1828 diff -Nru a/kernel/panic.c b/kernel/panic.c
1829 --- a/kernel/panic.c    2004-08-26 21:34:52 +02:00
1830 +++ b/kernel/panic.c    2004-08-26 21:34:52 +02:00
1831 @@ -19,6 +19,7 @@
1832  #include <linux/syscalls.h>
1833  #include <linux/interrupt.h>
1834  #include <linux/nmi.h>
1835 +#include "../drivers/video/fbsplash.h"
1836  
1837  int panic_timeout;
1838  int panic_on_oops;
1839 @@ -76,6 +77,8 @@
1840                  * We can't use the "normal" timers since we just panicked..
1841                  */
1842                 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
1843 +               fbsplash_verbose();
1844 +               
1845                 for (i = 0; i < panic_timeout; i++) {
1846                         touch_nmi_watchdog();
1847                         mdelay(1000);
1848 @@ -99,6 +102,8 @@
1849          disabled_wait(caller);
1850  #endif
1851         local_irq_enable();
1852 +       fbsplash_verbose();
1853 +
1854         for (;;)
1855                 ;
1856  }
1857 diff -Nru a/kernel/power/console.c b/kernel/power/console.c
1858 --- a/kernel/power/console.c    2004-08-26 21:34:52 +02:00
1859 +++ b/kernel/power/console.c    2004-08-26 21:34:52 +02:00
1860 @@ -9,6 +9,8 @@
1861  #include <linux/console.h>
1862  #include "power.h"
1863  
1864 +#include "../drivers/video/fbsplash.h"
1865 +
1866  static int new_loglevel = 10;
1867  static int orig_loglevel;
1868  static int orig_fgconsole, orig_kmsg;
1869 @@ -19,6 +21,9 @@
1870         console_loglevel = new_loglevel;
1871  
1872  #ifdef SUSPEND_CONSOLE
1873 +       if (fbsplash_issilent)
1874 +               fbsplash_verbose();
1875 +
1876         acquire_console_sem();
1877  
1878         orig_fgconsole = fg_console;
1879 diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
1880 --- a/kernel/sysctl.c   2004-08-26 21:34:52 +02:00
1881 +++ b/kernel/sysctl.c   2004-08-26 21:34:52 +02:00
1882 @@ -83,6 +83,9 @@
1883  #ifdef CONFIG_HOTPLUG
1884  extern char hotplug_path[];
1885  #endif
1886 +#ifdef CONFIG_FB_SPLASH
1887 +extern char fbsplash_path[];
1888 +#endif
1889  #ifdef CONFIG_CHR_DEV_SG
1890  extern int sg_big_buff;
1891  #endif
1892 @@ -409,6 +412,17 @@
1893                 .ctl_name       = KERN_HOTPLUG,
1894                 .procname       = "hotplug",
1895                 .data           = &hotplug_path,
1896 +               .maxlen         = KMOD_PATH_LEN,
1897 +               .mode           = 0644,
1898 +               .proc_handler   = &proc_dostring,
1899 +               .strategy       = &sysctl_string,
1900 +       },
1901 +#endif
1902 +#ifdef CONFIG_FB_SPLASH
1903 +       {
1904 +               .ctl_name       = KERN_FBSPLASH,
1905 +               .procname       = "fbsplash",
1906 +               .data           = &fbsplash_path,
1907                 .maxlen         = KMOD_PATH_LEN,
1908                 .mode           = 0644,
1909                 .proc_handler   = &proc_dostring,
This page took 0.176419 seconds and 3 git commands to generate.