Gentoo Archives: gentoo-commits

From: "Mike Pagano (mpagano)" <mpagano@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1618 - genpatches-2.6/trunk/2.6.31
Date: Thu, 08 Oct 2009 01:21:05
Message-Id: E1Mvhge-00032r-HV@stork.gentoo.org
1 Author: mpagano
2 Date: 2009-10-08 01:20:56 +0000 (Thu, 08 Oct 2009)
3 New Revision: 1618
4
5 Added:
6 genpatches-2.6/trunk/2.6.31/1002_linux-2.6.31.3.patch
7 genpatches-2.6/trunk/2.6.31/4200_fbcondecor-0.9.6.patch
8 Removed:
9 genpatches-2.6/trunk/2.6.31/4202_fbcondecor-0.9.6.patch
10 Modified:
11 genpatches-2.6/trunk/2.6.31/0000_README
12 Log:
13 Linux patch 2.6.31.3 and fix for fbcondecor for 2.6.31.3
14
15 Modified: genpatches-2.6/trunk/2.6.31/0000_README
16 ===================================================================
17 --- genpatches-2.6/trunk/2.6.31/0000_README 2009-10-06 15:22:02 UTC (rev 1617)
18 +++ genpatches-2.6/trunk/2.6.31/0000_README 2009-10-08 01:20:56 UTC (rev 1618)
19 @@ -47,11 +47,19 @@
20 From: http://www.kernel.org
21 Desc: Linux 2.6.31.2
22
23 +Patch: 1002_linux-2.6.31.3.patch
24 +From: http://www.kernel.org
25 +Desc: Linux 2.6.31.3
26 +
27 +Patch: 1001_linux-2.6.31.2.patch
28 +From: http://www.kernel.org
29 +Desc: Linux 2.6.31.2
30 +
31 Patch: 4100_dm-bbr.patch
32 From: EVMS 2.5.2
33 Desc: Bad block relocation support for LiveCD users
34
35 -Patch: 4202_fbcondecor-0.9.6.patch
36 +Patch: 4200_fbcondecor-0.9.6.patch
37 From: http://dev.gentoo.org/~spock
38 Desc: Bootsplash successor by Michal Januszewski
39
40
41 Added: genpatches-2.6/trunk/2.6.31/1002_linux-2.6.31.3.patch
42 ===================================================================
43 --- genpatches-2.6/trunk/2.6.31/1002_linux-2.6.31.3.patch (rev 0)
44 +++ genpatches-2.6/trunk/2.6.31/1002_linux-2.6.31.3.patch 2009-10-08 01:20:56 UTC (rev 1618)
45 @@ -0,0 +1,22 @@
46 +diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
47 +index 549bd0f..fa4ce67 100644
48 +--- a/drivers/char/tty_port.c
49 ++++ b/drivers/char/tty_port.c
50 +@@ -99,7 +99,7 @@ EXPORT_SYMBOL(tty_port_tty_set);
51 + static void tty_port_shutdown(struct tty_port *port)
52 + {
53 + if (port->ops->shutdown &&
54 +- test_and_clear_bit(ASYNC_INITIALIZED, &port->flags))
55 ++ test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
56 + port->ops->shutdown(port);
57 +
58 + }
59 +@@ -309,7 +309,7 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
60 + port->ops->drop(port);
61 + return 0;
62 + }
63 +- set_bit(ASYNC_CLOSING, &port->flags);
64 ++ set_bit(ASYNCB_CLOSING, &port->flags);
65 + tty->closing = 1;
66 + spin_unlock_irqrestore(&port->lock, flags);
67 + /* Don't block on a stalled port, just pull the chain */
68
69 Added: genpatches-2.6/trunk/2.6.31/4200_fbcondecor-0.9.6.patch
70 ===================================================================
71 --- genpatches-2.6/trunk/2.6.31/4200_fbcondecor-0.9.6.patch (rev 0)
72 +++ genpatches-2.6/trunk/2.6.31/4200_fbcondecor-0.9.6.patch 2009-10-08 01:20:56 UTC (rev 1618)
73 @@ -0,0 +1,2130 @@
74 +diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
75 +index a618fd9..6eb4dc4 100644
76 +--- a/Documentation/fb/00-INDEX
77 ++++ b/Documentation/fb/00-INDEX
78 +@@ -15,6 +15,8 @@ deferred_io.txt
79 + - an introduction to deferred IO.
80 + fbcon.txt
81 + - intro to and usage guide for the framebuffer console (fbcon).
82 ++fbcondecor.txt
83 ++ - info on the Framebuffer Console Decoration
84 + framebuffer.txt
85 + - introduction to frame buffer devices.
86 + imacfb.txt
87 +diff --git a/Documentation/fb/fbcondecor.txt b/Documentation/fb/fbcondecor.txt
88 +new file mode 100644
89 +index 0000000..15889f3
90 +--- /dev/null
91 ++++ b/Documentation/fb/fbcondecor.txt
92 +@@ -0,0 +1,207 @@
93 ++What is it?
94 ++-----------
95 ++
96 ++The framebuffer decorations are a kernel feature which allows displaying a
97 ++background picture on selected consoles.
98 ++
99 ++What do I need to get it to work?
100 ++---------------------------------
101 ++
102 ++To get fbcondecor up-and-running you will have to:
103 ++ 1) get a copy of splashutils [1] or a similar program
104 ++ 2) get some fbcondecor themes
105 ++ 3) build the kernel helper program
106 ++ 4) build your kernel with the FB_CON_DECOR option enabled.
107 ++
108 ++To get fbcondecor operational right after fbcon initialization is finished, you
109 ++will have to include a theme and the kernel helper into your initramfs image.
110 ++Please refer to splashutils documentation for instructions on how to do that.
111 ++
112 ++[1] The splashutils package can be downloaded from:
113 ++ http://dev.gentoo.org/~spock/projects/splashutils/
114 ++
115 ++The userspace helper
116 ++--------------------
117 ++
118 ++The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the
119 ++kernel whenever an important event occurs and the kernel needs some kind of
120 ++job to be carried out. Important events include console switches and video
121 ++mode switches (the kernel requests background images and configuration
122 ++parameters for the current console). The fbcondecor helper must be accessible at
123 ++all times. If it's not, fbcondecor will be switched off automatically.
124 ++
125 ++It's possible to set path to the fbcondecor helper by writing it to
126 ++/proc/sys/kernel/fbcondecor.
127 ++
128 ++*****************************************************************************
129 ++
130 ++The information below is mostly technical stuff. There's probably no need to
131 ++read it unless you plan to develop a userspace helper.
132 ++
133 ++The fbcondecor protocol
134 ++-----------------------
135 ++
136 ++The fbcondecor protocol defines a communication interface between the kernel and
137 ++the userspace fbcondecor helper.
138 ++
139 ++The kernel side is responsible for:
140 ++
141 ++ * rendering console text, using an image as a background (instead of a
142 ++ standard solid color fbcon uses),
143 ++ * accepting commands from the user via ioctls on the fbcondecor device,
144 ++ * calling the userspace helper to set things up as soon as the fb subsystem
145 ++ is initialized.
146 ++
147 ++The userspace helper is responsible for everything else, including parsing
148 ++configuration files, decompressing the image files whenever the kernel needs
149 ++it, and communicating with the kernel if necessary.
150 ++
151 ++The fbcondecor protocol specifies how communication is done in both ways:
152 ++kernel->userspace and userspace->helper.
153 ++
154 ++Kernel -> Userspace
155 ++-------------------
156 ++
157 ++The kernel communicates with the userspace helper by calling it and specifying
158 ++the task to be done in a series of arguments.
159 ++
160 ++The arguments follow the pattern:
161 ++<fbcondecor protocol version> <command> <parameters>
162 ++
163 ++All commands defined in fbcondecor protocol v2 have the following parameters:
164 ++ virtual console
165 ++ framebuffer number
166 ++ theme
167 ++
168 ++Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the
169 ++framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used.
170 ++
171 ++Fbcondecor protocol v2 specifies the following commands:
172 ++
173 ++getpic
174 ++------
175 ++ The kernel issues this command to request image data. It's up to the
176 ++ userspace helper to find a background image appropriate for the specified
177 ++ theme and the current resolution. The userspace helper should respond by
178 ++ issuing the FBIOCONDECOR_SETPIC ioctl.
179 ++
180 ++init
181 ++----
182 ++ The kernel issues this command after the fbcondecor device is created and
183 ++ the fbcondecor interface is initialized. Upon receiving 'init', the userspace
184 ++ helper should parse the kernel command line (/proc/cmdline) or otherwise
185 ++ decide whether fbcondecor is to be activated.
186 ++
187 ++ To activate fbcondecor on the first console the helper should issue the
188 ++ FBIOCONDECOR_SETCFG, FBIOCONDECOR_SETPIC and FBIOCONDECOR_SETSTATE commands,
189 ++ in the above-mentioned order.
190 ++
191 ++ When the userspace helper is called in an early phase of the boot process
192 ++ (right after the initialization of fbcon), no filesystems will be mounted.
193 ++ The helper program should mount sysfs and then create the appropriate
194 ++ framebuffer, fbcondecor and tty0 devices (if they don't already exist) to get
195 ++ current display settings and to be able to communicate with the kernel side.
196 ++ It should probably also mount the procfs to be able to parse the kernel
197 ++ command line parameters.
198 ++
199 ++ Note that the console sem is not held when the kernel calls fbcondecor_helper
200 ++ with the 'init' command. The fbcondecor helper should perform all ioctls with
201 ++ origin set to FBCON_DECOR_IO_ORIG_USER.
202 ++
203 ++modechange
204 ++----------
205 ++ The kernel issues this command on a mode change. The helper's response should
206 ++ be similar to the response to the 'init' command. Note that this time the
207 ++ console sem is held and all ioctls must be performed with origin set to
208 ++ FBCON_DECOR_IO_ORIG_KERNEL.
209 ++
210 ++
211 ++Userspace -> Kernel
212 ++-------------------
213 ++
214 ++Userspace programs can communicate with fbcondecor via ioctls on the
215 ++fbcondecor device. These ioctls are to be used by both the userspace helper
216 ++(called only by the kernel) and userspace configuration tools (run by the users).
217 ++
218 ++The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL
219 ++when doing the appropriate ioctls. All userspace configuration tools should
220 ++use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin
221 ++field when performing ioctls from the kernel helper will most likely result
222 ++in a console deadlock.
223 ++
224 ++FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console
225 ++semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire
226 ++the console sem.
227 ++
228 ++The framebuffer console decoration provides the following ioctls (all defined in
229 ++linux/fb.h):
230 ++
231 ++FBIOCONDECOR_SETPIC
232 ++description: loads a background picture for a virtual console
233 ++argument: struct fbcon_decor_iowrapper*; data: struct fb_image*
234 ++notes:
235 ++If called for consoles other than the current foreground one, the picture data
236 ++will be ignored.
237 ++
238 ++If the current virtual console is running in a 8-bpp mode, the cmap substruct
239 ++of fb_image has to be filled appropriately: start should be set to 16 (first
240 ++16 colors are reserved for fbcon), len to a value <= 240 and red, green and
241 ++blue should point to valid cmap data. The transp field is ingored. The fields
242 ++dx, dy, bg_color, fg_color in fb_image are ignored as well.
243 ++
244 ++FBIOCONDECOR_SETCFG
245 ++description: sets the fbcondecor config for a virtual console
246 ++argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
247 ++notes: The structure has to be filled with valid data.
248 ++
249 ++FBIOCONDECOR_GETCFG
250 ++description: gets the fbcondecor config for a virtual console
251 ++argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
252 ++
253 ++FBIOCONDECOR_SETSTATE
254 ++description: sets the fbcondecor state for a virtual console
255 ++argument: struct fbcon_decor_iowrapper*; data: unsigned int*
256 ++ values: 0 = disabled, 1 = enabled.
257 ++
258 ++FBIOCONDECOR_GETSTATE
259 ++description: gets the fbcondecor state for a virtual console
260 ++argument: struct fbcon_decor_iowrapper*; data: unsigned int*
261 ++ values: as in FBIOCONDECOR_SETSTATE
262 ++
263 ++Info on used structures:
264 ++
265 ++Definition of struct vc_decor can be found in linux/console_decor.h. It's
266 ++heavily commented. Note that the 'theme' field should point to a string
267 ++no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is
268 ++performed, the theme field should point to a char buffer of length
269 ++FBCON_DECOR_THEME_LEN.
270 ++
271 ++Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h.
272 ++The fields in this struct have the following meaning:
273 ++
274 ++vc:
275 ++Virtual console number.
276 ++
277 ++origin:
278 ++Specifies if the ioctl is performed as a response to a kernel request. The
279 ++fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace
280 ++programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to
281 ++avoid console semaphore deadlocks.
282 ++
283 ++data:
284 ++Pointer to a data structure appropriate for the performed ioctl. Type of
285 ++the data struct is specified in the ioctls description.
286 ++
287 ++*****************************************************************************
288 ++
289 ++Credit
290 ++------
291 ++
292 ++Original 'bootsplash' project & implementation by:
293 ++ Volker Poplawski <volker@×××××××××.de>, Stefan Reinauer <stepan@××××.de>,
294 ++ Steffen Winterfeldt <snwint@××××.de>, Michael Schroeder <mls@××××.de>,
295 ++ Ken Wimer <wimer@××××.de>.
296 ++
297 ++Fbcondecor, fbcondecor protocol design, current implementation & docs by:
298 ++ Michal Januszewski <spock@g.o>
299 ++
300 +diff --git a/drivers/Makefile b/drivers/Makefile
301 +index bc4205d..794ce71 100644
302 +--- a/drivers/Makefile
303 ++++ b/drivers/Makefile
304 +@@ -9,6 +9,9 @@ obj-y += gpio/
305 + obj-$(CONFIG_PCI) += pci/
306 + obj-$(CONFIG_PARISC) += parisc/
307 + obj-$(CONFIG_RAPIDIO) += rapidio/
308 ++# char/ comes before serial/ etc so that the VT console is the boot-time
309 ++# default.
310 ++obj-y += char/
311 + obj-y += video/
312 + obj-$(CONFIG_ACPI) += acpi/
313 + # PnP must come after ACPI since it will eventually need to check if acpi
314 +@@ -21,10 +24,6 @@ obj-$(CONFIG_XEN) += xen/
315 + # regulators early, since some subsystems rely on them to initialize
316 + obj-$(CONFIG_REGULATOR) += regulator/
317 +
318 +-# char/ comes before serial/ etc so that the VT console is the boot-time
319 +-# default.
320 +-obj-y += char/
321 +-
322 + # gpu/ comes after char for AGP vs DRM startup
323 + obj-y += gpu/
324 +
325 +diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
326 +index 3b54b39..23ce357 100644
327 +--- a/drivers/video/Kconfig
328 ++++ b/drivers/video/Kconfig
329 +@@ -1160,7 +1160,6 @@ config FB_MATROX
330 + select FB_CFB_FILLRECT
331 + select FB_CFB_COPYAREA
332 + select FB_CFB_IMAGEBLIT
333 +- select FB_TILEBLITTING
334 + select FB_MACMODES if PPC_PMAC
335 + ---help---
336 + Say Y here if you have a Matrox Millennium, Matrox Millennium II,
337 +diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
338 +index 2f50a80..aa73fb7 100644
339 +--- a/drivers/video/console/Kconfig
340 ++++ b/drivers/video/console/Kconfig
341 +@@ -128,6 +128,19 @@ config FRAMEBUFFER_CONSOLE_ROTATION
342 + such that other users of the framebuffer will remain normally
343 + oriented.
344 +
345 ++config FB_CON_DECOR
346 ++ bool "Support for the Framebuffer Console Decorations"
347 ++ depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
348 ++ default n
349 ++ ---help---
350 ++ This option enables support for framebuffer console decorations which
351 ++ makes it possible to display images in the background of the system
352 ++ consoles. Note that userspace utilities are necessary in order to take
353 ++ advantage of these features. Refer to Documentation/fb/fbcondecor.txt
354 ++ for more information.
355 ++
356 ++ If unsure, say N.
357 ++
358 + config STI_CONSOLE
359 + bool "STI text console"
360 + depends on PARISC
361 +diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
362 +index ac46cc3..e300ea0 100644
363 +--- a/drivers/video/console/Makefile
364 ++++ b/drivers/video/console/Makefile
365 +@@ -35,6 +35,7 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
366 + fbcon_ccw.o
367 + endif
368 +
369 ++obj-$(CONFIG_FB_CON_DECOR) += fbcondecor.o cfbcondecor.o
370 + obj-$(CONFIG_FB_STI) += sticore.o font.o
371 +
372 + ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
373 +diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
374 +index 69864b1..77c1feb 100644
375 +--- a/drivers/video/console/bitblit.c
376 ++++ b/drivers/video/console/bitblit.c
377 +@@ -17,6 +17,7 @@
378 + #include <linux/console.h>
379 + #include <asm/types.h>
380 + #include "fbcon.h"
381 ++#include "fbcondecor.h"
382 +
383 + /*
384 + * Accelerated handlers.
385 +@@ -54,6 +55,13 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
386 + area.height = height * vc->vc_font.height;
387 + area.width = width * vc->vc_font.width;
388 +
389 ++ if (fbcon_decor_active(info, vc)) {
390 ++ area.sx += vc->vc_decor.tx;
391 ++ area.sy += vc->vc_decor.ty;
392 ++ area.dx += vc->vc_decor.tx;
393 ++ area.dy += vc->vc_decor.ty;
394 ++ }
395 ++
396 + info->fbops->fb_copyarea(info, &area);
397 + }
398 +
399 +@@ -379,11 +387,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
400 + cursor.image.depth = 1;
401 + cursor.rop = ROP_XOR;
402 +
403 +- if (info->fbops->fb_cursor)
404 +- err = info->fbops->fb_cursor(info, &cursor);
405 ++ if (fbcon_decor_active(info, vc)) {
406 ++ fbcon_decor_cursor(info, &cursor);
407 ++ } else {
408 ++ if (info->fbops->fb_cursor)
409 ++ err = info->fbops->fb_cursor(info, &cursor);
410 +
411 +- if (err)
412 +- soft_cursor(info, &cursor);
413 ++ if (err)
414 ++ soft_cursor(info, &cursor);
415 ++ }
416 +
417 + ops->cursor_reset = 0;
418 + }
419 +diff --git a/drivers/video/console/cfbcondecor.c b/drivers/video/console/cfbcondecor.c
420 +new file mode 100644
421 +index 0000000..7654ec6
422 +--- /dev/null
423 ++++ b/drivers/video/console/cfbcondecor.c
424 +@@ -0,0 +1,471 @@
425 ++/*
426 ++ * linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions
427 ++ *
428 ++ * Copyright (C) 2004 Michal Januszewski <spock@g.o>
429 ++ *
430 ++ * Code based upon "Bootdecor" (C) 2001-2003
431 ++ * Volker Poplawski <volker@×××××××××.de>,
432 ++ * Stefan Reinauer <stepan@××××.de>,
433 ++ * Steffen Winterfeldt <snwint@××××.de>,
434 ++ * Michael Schroeder <mls@××××.de>,
435 ++ * Ken Wimer <wimer@××××.de>.
436 ++ *
437 ++ * This file is subject to the terms and conditions of the GNU General Public
438 ++ * License. See the file COPYING in the main directory of this archive for
439 ++ * more details.
440 ++ */
441 ++#include <linux/module.h>
442 ++#include <linux/types.h>
443 ++#include <linux/fb.h>
444 ++#include <linux/selection.h>
445 ++#include <linux/vt_kern.h>
446 ++#include <asm/irq.h>
447 ++#include <asm/system.h>
448 ++
449 ++#include "fbcon.h"
450 ++#include "fbcondecor.h"
451 ++
452 ++#define parse_pixel(shift,bpp,type) \
453 ++ do { \
454 ++ if (d & (0x80 >> (shift))) \
455 ++ dd2[(shift)] = fgx; \
456 ++ else \
457 ++ dd2[(shift)] = transparent ? *(type *)decor_src : bgx; \
458 ++ decor_src += (bpp); \
459 ++ } while (0) \
460 ++
461 ++extern int get_color(struct vc_data *vc, struct fb_info *info,
462 ++ u16 c, int is_fg);
463 ++
464 ++void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc)
465 ++{
466 ++ int i, j, k;
467 ++ int minlen = min(min(info->var.red.length, info->var.green.length),
468 ++ info->var.blue.length);
469 ++ u32 col;
470 ++
471 ++ for (j = i = 0; i < 16; i++) {
472 ++ k = color_table[i];
473 ++
474 ++ col = ((vc->vc_palette[j++] >> (8-minlen))
475 ++ << info->var.red.offset);
476 ++ col |= ((vc->vc_palette[j++] >> (8-minlen))
477 ++ << info->var.green.offset);
478 ++ col |= ((vc->vc_palette[j++] >> (8-minlen))
479 ++ << info->var.blue.offset);
480 ++ ((u32 *)info->pseudo_palette)[k] = col;
481 ++ }
482 ++}
483 ++
484 ++void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height,
485 ++ int width, u8* src, u32 fgx, u32 bgx, u8 transparent)
486 ++{
487 ++ unsigned int x, y;
488 ++ u32 dd;
489 ++ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
490 ++ unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
491 ++ unsigned int ds = (ypos * info->var.xres + xpos) * bytespp;
492 ++ u16 dd2[4];
493 ++
494 ++ u8* decor_src = (u8 *)(info->bgdecor.data + ds);
495 ++ u8* dst = (u8 *)(info->screen_base + d);
496 ++
497 ++ if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
498 ++ return;
499 ++
500 ++ for (y = 0; y < height; y++) {
501 ++ switch (info->var.bits_per_pixel) {
502 ++
503 ++ case 32:
504 ++ for (x = 0; x < width; x++) {
505 ++
506 ++ if ((x & 7) == 0)
507 ++ d = *src++;
508 ++ if (d & 0x80)
509 ++ dd = fgx;
510 ++ else
511 ++ dd = transparent ?
512 ++ *(u32 *)decor_src : bgx;
513 ++
514 ++ d <<= 1;
515 ++ decor_src += 4;
516 ++ fb_writel(dd, dst);
517 ++ dst += 4;
518 ++ }
519 ++ break;
520 ++ case 24:
521 ++ for (x = 0; x < width; x++) {
522 ++
523 ++ if ((x & 7) == 0)
524 ++ d = *src++;
525 ++ if (d & 0x80)
526 ++ dd = fgx;
527 ++ else
528 ++ dd = transparent ?
529 ++ (*(u32 *)decor_src & 0xffffff) : bgx;
530 ++
531 ++ d <<= 1;
532 ++ decor_src += 3;
533 ++#ifdef __LITTLE_ENDIAN
534 ++ fb_writew(dd & 0xffff, dst);
535 ++ dst += 2;
536 ++ fb_writeb((dd >> 16), dst);
537 ++#else
538 ++ fb_writew(dd >> 8, dst);
539 ++ dst += 2;
540 ++ fb_writeb(dd & 0xff, dst);
541 ++#endif
542 ++ dst++;
543 ++ }
544 ++ break;
545 ++ case 16:
546 ++ for (x = 0; x < width; x += 2) {
547 ++ if ((x & 7) == 0)
548 ++ d = *src++;
549 ++
550 ++ parse_pixel(0, 2, u16);
551 ++ parse_pixel(1, 2, u16);
552 ++#ifdef __LITTLE_ENDIAN
553 ++ dd = dd2[0] | (dd2[1] << 16);
554 ++#else
555 ++ dd = dd2[1] | (dd2[0] << 16);
556 ++#endif
557 ++ d <<= 2;
558 ++ fb_writel(dd, dst);
559 ++ dst += 4;
560 ++ }
561 ++ break;
562 ++
563 ++ case 8:
564 ++ for (x = 0; x < width; x += 4) {
565 ++ if ((x & 7) == 0)
566 ++ d = *src++;
567 ++
568 ++ parse_pixel(0, 1, u8);
569 ++ parse_pixel(1, 1, u8);
570 ++ parse_pixel(2, 1, u8);
571 ++ parse_pixel(3, 1, u8);
572 ++
573 ++#ifdef __LITTLE_ENDIAN
574 ++ dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
575 ++#else
576 ++ dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
577 ++#endif
578 ++ d <<= 4;
579 ++ fb_writel(dd, dst);
580 ++ dst += 4;
581 ++ }
582 ++ }
583 ++
584 ++ dst += info->fix.line_length - width * bytespp;
585 ++ decor_src += (info->var.xres - width) * bytespp;
586 ++ }
587 ++}
588 ++
589 ++#define cc2cx(a) \
590 ++ ((info->fix.visual == FB_VISUAL_TRUECOLOR || \
591 ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \
592 ++ ((u32*)info->pseudo_palette)[a] : a)
593 ++
594 ++void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info,
595 ++ const unsigned short *s, int count, int yy, int xx)
596 ++{
597 ++ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
598 ++ struct fbcon_ops *ops = info->fbcon_par;
599 ++ int fg_color, bg_color, transparent;
600 ++ u8 *src;
601 ++ u32 bgx, fgx;
602 ++ u16 c = scr_readw(s);
603 ++
604 ++ fg_color = get_color(vc, info, c, 1);
605 ++ bg_color = get_color(vc, info, c, 0);
606 ++
607 ++ /* Don't paint the background image if console is blanked */
608 ++ transparent = ops->blank_state ? 0 :
609 ++ (vc->vc_decor.bg_color == bg_color);
610 ++
611 ++ xx = xx * vc->vc_font.width + vc->vc_decor.tx;
612 ++ yy = yy * vc->vc_font.height + vc->vc_decor.ty;
613 ++
614 ++ fgx = cc2cx(fg_color);
615 ++ bgx = cc2cx(bg_color);
616 ++
617 ++ while (count--) {
618 ++ c = scr_readw(s++);
619 ++ src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
620 ++ ((vc->vc_font.width + 7) >> 3);
621 ++
622 ++ fbcon_decor_renderc(info, yy, xx, vc->vc_font.height,
623 ++ vc->vc_font.width, src, fgx, bgx, transparent);
624 ++ xx += vc->vc_font.width;
625 ++ }
626 ++}
627 ++
628 ++void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor)
629 ++{
630 ++ int i;
631 ++ unsigned int dsize, s_pitch;
632 ++ struct fbcon_ops *ops = info->fbcon_par;
633 ++ struct vc_data* vc;
634 ++ u8 *src;
635 ++
636 ++ /* we really don't need any cursors while the console is blanked */
637 ++ if (info->state != FBINFO_STATE_RUNNING || ops->blank_state)
638 ++ return;
639 ++
640 ++ vc = vc_cons[ops->currcon].d;
641 ++
642 ++ src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC);
643 ++ if (!src)
644 ++ return;
645 ++
646 ++ s_pitch = (cursor->image.width + 7) >> 3;
647 ++ dsize = s_pitch * cursor->image.height;
648 ++ if (cursor->enable) {
649 ++ switch (cursor->rop) {
650 ++ case ROP_XOR:
651 ++ for (i = 0; i < dsize; i++)
652 ++ src[i] = cursor->image.data[i] ^ cursor->mask[i];
653 ++ break;
654 ++ case ROP_COPY:
655 ++ default:
656 ++ for (i = 0; i < dsize; i++)
657 ++ src[i] = cursor->image.data[i] & cursor->mask[i];
658 ++ break;
659 ++ }
660 ++ } else
661 ++ memcpy(src, cursor->image.data, dsize);
662 ++
663 ++ fbcon_decor_renderc(info,
664 ++ cursor->image.dy + vc->vc_decor.ty,
665 ++ cursor->image.dx + vc->vc_decor.tx,
666 ++ cursor->image.height,
667 ++ cursor->image.width,
668 ++ (u8*)src,
669 ++ cc2cx(cursor->image.fg_color),
670 ++ cc2cx(cursor->image.bg_color),
671 ++ cursor->image.bg_color == vc->vc_decor.bg_color);
672 ++
673 ++ kfree(src);
674 ++}
675 ++
676 ++static void decorset(u8 *dst, int height, int width, int dstbytes,
677 ++ u32 bgx, int bpp)
678 ++{
679 ++ int i;
680 ++
681 ++ if (bpp == 8)
682 ++ bgx |= bgx << 8;
683 ++ if (bpp == 16 || bpp == 8)
684 ++ bgx |= bgx << 16;
685 ++
686 ++ while (height-- > 0) {
687 ++ u8 *p = dst;
688 ++
689 ++ switch (bpp) {
690 ++
691 ++ case 32:
692 ++ for (i=0; i < width; i++) {
693 ++ fb_writel(bgx, p); p += 4;
694 ++ }
695 ++ break;
696 ++ case 24:
697 ++ for (i=0; i < width; i++) {
698 ++#ifdef __LITTLE_ENDIAN
699 ++ fb_writew((bgx & 0xffff),(u16*)p); p += 2;
700 ++ fb_writeb((bgx >> 16),p++);
701 ++#else
702 ++ fb_writew((bgx >> 8),(u16*)p); p += 2;
703 ++ fb_writeb((bgx & 0xff),p++);
704 ++#endif
705 ++ }
706 ++ case 16:
707 ++ for (i=0; i < width/4; i++) {
708 ++ fb_writel(bgx,p); p += 4;
709 ++ fb_writel(bgx,p); p += 4;
710 ++ }
711 ++ if (width & 2) {
712 ++ fb_writel(bgx,p); p += 4;
713 ++ }
714 ++ if (width & 1)
715 ++ fb_writew(bgx,(u16*)p);
716 ++ break;
717 ++ case 8:
718 ++ for (i=0; i < width/4; i++) {
719 ++ fb_writel(bgx,p); p += 4;
720 ++ }
721 ++
722 ++ if (width & 2) {
723 ++ fb_writew(bgx,p); p += 2;
724 ++ }
725 ++ if (width & 1)
726 ++ fb_writeb(bgx,(u8*)p);
727 ++ break;
728 ++
729 ++ }
730 ++ dst += dstbytes;
731 ++ }
732 ++}
733 ++
734 ++void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
735 ++ int srclinebytes, int bpp)
736 ++{
737 ++ int i;
738 ++
739 ++ while (height-- > 0) {
740 ++ u32 *p = (u32 *)dst;
741 ++ u32 *q = (u32 *)src;
742 ++
743 ++ switch (bpp) {
744 ++
745 ++ case 32:
746 ++ for (i=0; i < width; i++)
747 ++ fb_writel(*q++, p++);
748 ++ break;
749 ++ case 24:
750 ++ for (i=0; i < (width*3/4); i++)
751 ++ fb_writel(*q++, p++);
752 ++ if ((width*3) % 4) {
753 ++ if (width & 2) {
754 ++ fb_writeb(*(u8*)q, (u8*)p);
755 ++ } else if (width & 1) {
756 ++ fb_writew(*(u16*)q, (u16*)p);
757 ++ fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2));
758 ++ }
759 ++ }
760 ++ break;
761 ++ case 16:
762 ++ for (i=0; i < width/4; i++) {
763 ++ fb_writel(*q++, p++);
764 ++ fb_writel(*q++, p++);
765 ++ }
766 ++ if (width & 2)
767 ++ fb_writel(*q++, p++);
768 ++ if (width & 1)
769 ++ fb_writew(*(u16*)q, (u16*)p);
770 ++ break;
771 ++ case 8:
772 ++ for (i=0; i < width/4; i++)
773 ++ fb_writel(*q++, p++);
774 ++
775 ++ if (width & 2) {
776 ++ fb_writew(*(u16*)q, (u16*)p);
777 ++ q = (u32*) ((u16*)q + 1);
778 ++ p = (u32*) ((u16*)p + 1);
779 ++ }
780 ++ if (width & 1)
781 ++ fb_writeb(*(u8*)q, (u8*)p);
782 ++ break;
783 ++ }
784 ++
785 ++ dst += linebytes;
786 ++ src += srclinebytes;
787 ++ }
788 ++}
789 ++
790 ++static void decorfill(struct fb_info *info, int sy, int sx, int height,
791 ++ int width)
792 ++{
793 ++ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
794 ++ int d = sy * info->fix.line_length + sx * bytespp;
795 ++ int ds = (sy * info->var.xres + sx) * bytespp;
796 ++
797 ++ fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds),
798 ++ height, width, info->fix.line_length, info->var.xres * bytespp,
799 ++ info->var.bits_per_pixel);
800 ++}
801 ++
802 ++void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
803 ++ int height, int width)
804 ++{
805 ++ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
806 ++ struct fbcon_ops *ops = info->fbcon_par;
807 ++ u8 *dst;
808 ++ int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info);
809 ++
810 ++ transparent = (vc->vc_decor.bg_color == bg_color);
811 ++ sy = sy * vc->vc_font.height + vc->vc_decor.ty;
812 ++ sx = sx * vc->vc_font.width + vc->vc_decor.tx;
813 ++ height *= vc->vc_font.height;
814 ++ width *= vc->vc_font.width;
815 ++
816 ++ /* Don't paint the background image if console is blanked */
817 ++ if (transparent && !ops->blank_state) {
818 ++ decorfill(info, sy, sx, height, width);
819 ++ } else {
820 ++ dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
821 ++ sx * ((info->var.bits_per_pixel + 7) >> 3));
822 ++ decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
823 ++ info->var.bits_per_pixel);
824 ++ }
825 ++}
826 ++
827 ++void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info,
828 ++ int bottom_only)
829 ++{
830 ++ unsigned int tw = vc->vc_cols*vc->vc_font.width;
831 ++ unsigned int th = vc->vc_rows*vc->vc_font.height;
832 ++
833 ++ if (!bottom_only) {
834 ++ /* top margin */
835 ++ decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres);
836 ++ /* left margin */
837 ++ decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx);
838 ++ /* right margin */
839 ++ decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th,
840 ++ info->var.xres - vc->vc_decor.tx - tw);
841 ++ }
842 ++ decorfill(info, vc->vc_decor.ty + th, 0,
843 ++ info->var.yres - vc->vc_decor.ty - th, info->var.xres);
844 ++}
845 ++
846 ++void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y,
847 ++ int sx, int dx, int width)
848 ++{
849 ++ u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
850 ++ u16 *s = d + (dx - sx);
851 ++ u16 *start = d;
852 ++ u16 *ls = d;
853 ++ u16 *le = d + width;
854 ++ u16 c;
855 ++ int x = dx;
856 ++ u16 attr = 1;
857 ++
858 ++ do {
859 ++ c = scr_readw(d);
860 ++ if (attr != (c & 0xff00)) {
861 ++ attr = c & 0xff00;
862 ++ if (d > start) {
863 ++ fbcon_decor_putcs(vc, info, start, d - start, y, x);
864 ++ x += d - start;
865 ++ start = d;
866 ++ }
867 ++ }
868 ++ if (s >= ls && s < le && c == scr_readw(s)) {
869 ++ if (d > start) {
870 ++ fbcon_decor_putcs(vc, info, start, d - start, y, x);
871 ++ x += d - start + 1;
872 ++ start = d + 1;
873 ++ } else {
874 ++ x++;
875 ++ start++;
876 ++ }
877 ++ }
878 ++ s++;
879 ++ d++;
880 ++ } while (d < le);
881 ++ if (d > start)
882 ++ fbcon_decor_putcs(vc, info, start, d - start, y, x);
883 ++}
884 ++
885 ++void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank)
886 ++{
887 ++ if (blank) {
888 ++ decorset((u8 *)info->screen_base, info->var.yres, info->var.xres,
889 ++ info->fix.line_length, 0, info->var.bits_per_pixel);
890 ++ } else {
891 ++ update_screen(vc);
892 ++ fbcon_decor_clear_margins(vc, info, 0);
893 ++ }
894 ++}
895 ++
896 +diff --git a/drivers/video/console/fbcondecor.c b/drivers/video/console/fbcondecor.c
897 +new file mode 100644
898 +index 0000000..a0b4ae3
899 +--- /dev/null
900 ++++ b/drivers/video/console/fbcondecor.c
901 +@@ -0,0 +1,561 @@
902 ++/*
903 ++ * linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations
904 ++ *
905 ++ * Copyright (C) 2004-2009 Michal Januszewski <spock@g.o>
906 ++ *
907 ++ * Code based upon "Bootsplash" (C) 2001-2003
908 ++ * Volker Poplawski <volker@×××××××××.de>,
909 ++ * Stefan Reinauer <stepan@××××.de>,
910 ++ * Steffen Winterfeldt <snwint@××××.de>,
911 ++ * Michael Schroeder <mls@××××.de>,
912 ++ * Ken Wimer <wimer@××××.de>.
913 ++ *
914 ++ * Compat ioctl support by Thorsten Klein <TK@××××××××××××××.de>.
915 ++ *
916 ++ * This file is subject to the terms and conditions of the GNU General Public
917 ++ * License. See the file COPYING in the main directory of this archive for
918 ++ * more details.
919 ++ *
920 ++ */
921 ++#include <linux/module.h>
922 ++#include <linux/kernel.h>
923 ++#include <linux/string.h>
924 ++#include <linux/types.h>
925 ++#include <linux/fb.h>
926 ++#include <linux/vt_kern.h>
927 ++#include <linux/vmalloc.h>
928 ++#include <linux/unistd.h>
929 ++#include <linux/syscalls.h>
930 ++#include <linux/init.h>
931 ++#include <linux/proc_fs.h>
932 ++#include <linux/workqueue.h>
933 ++#include <linux/kmod.h>
934 ++#include <linux/miscdevice.h>
935 ++#include <linux/device.h>
936 ++#include <linux/fs.h>
937 ++#include <linux/compat.h>
938 ++
939 ++#include <asm/uaccess.h>
940 ++#include <asm/irq.h>
941 ++#include <asm/system.h>
942 ++
943 ++#include "fbcon.h"
944 ++#include "fbcondecor.h"
945 ++
946 ++extern signed char con2fb_map[];
947 ++static int fbcon_decor_enable(struct vc_data *vc);
948 ++char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
949 ++static int initialized = 0;
950 ++
951 ++int fbcon_decor_call_helper(char* cmd, unsigned short vc)
952 ++{
953 ++ char *envp[] = {
954 ++ "HOME=/",
955 ++ "PATH=/sbin:/bin",
956 ++ NULL
957 ++ };
958 ++
959 ++ char tfb[5];
960 ++ char tcons[5];
961 ++ unsigned char fb = (int) con2fb_map[vc];
962 ++
963 ++ char *argv[] = {
964 ++ fbcon_decor_path,
965 ++ "2",
966 ++ cmd,
967 ++ tcons,
968 ++ tfb,
969 ++ vc_cons[vc].d->vc_decor.theme,
970 ++ NULL
971 ++ };
972 ++
973 ++ snprintf(tfb,5,"%d",fb);
974 ++ snprintf(tcons,5,"%d",vc);
975 ++
976 ++ return call_usermodehelper(fbcon_decor_path, argv, envp, 1);
977 ++}
978 ++
979 ++/* Disables fbcondecor on a virtual console; called with console sem held. */
980 ++int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw)
981 ++{
982 ++ struct fb_info* info;
983 ++
984 ++ if (!vc->vc_decor.state)
985 ++ return -EINVAL;
986 ++
987 ++ info = registered_fb[(int) con2fb_map[vc->vc_num]];
988 ++
989 ++ if (info == NULL)
990 ++ return -EINVAL;
991 ++
992 ++ vc->vc_decor.state = 0;
993 ++ vc_resize(vc, info->var.xres / vc->vc_font.width,
994 ++ info->var.yres / vc->vc_font.height);
995 ++
996 ++ if (fg_console == vc->vc_num && redraw) {
997 ++ redraw_screen(vc, 0);
998 ++ update_region(vc, vc->vc_origin +
999 ++ vc->vc_size_row * vc->vc_top,
1000 ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1001 ++ }
1002 ++
1003 ++ printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n",
1004 ++ vc->vc_num);
1005 ++
1006 ++ return 0;
1007 ++}
1008 ++
1009 ++/* Enables fbcondecor on a virtual console; called with console sem held. */
1010 ++static int fbcon_decor_enable(struct vc_data *vc)
1011 ++{
1012 ++ struct fb_info* info;
1013 ++
1014 ++ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1015 ++
1016 ++ if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 ||
1017 ++ info == NULL || vc->vc_decor.state || (!info->bgdecor.data &&
1018 ++ vc->vc_num == fg_console))
1019 ++ return -EINVAL;
1020 ++
1021 ++ vc->vc_decor.state = 1;
1022 ++ vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width,
1023 ++ vc->vc_decor.theight / vc->vc_font.height);
1024 ++
1025 ++ if (fg_console == vc->vc_num) {
1026 ++ redraw_screen(vc, 0);
1027 ++ update_region(vc, vc->vc_origin +
1028 ++ vc->vc_size_row * vc->vc_top,
1029 ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1030 ++ fbcon_decor_clear_margins(vc, info, 0);
1031 ++ }
1032 ++
1033 ++ printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n",
1034 ++ vc->vc_num);
1035 ++
1036 ++ return 0;
1037 ++}
1038 ++
1039 ++static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin)
1040 ++{
1041 ++ int ret;
1042 ++
1043 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1044 ++ acquire_console_sem();
1045 ++ if (!state)
1046 ++ ret = fbcon_decor_disable(vc, 1);
1047 ++ else
1048 ++ ret = fbcon_decor_enable(vc);
1049 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1050 ++ release_console_sem();
1051 ++
1052 ++ return ret;
1053 ++}
1054 ++
1055 ++static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state)
1056 ++{
1057 ++ *state = vc->vc_decor.state;
1058 ++}
1059 ++
1060 ++static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin)
1061 ++{
1062 ++ struct fb_info *info;
1063 ++ int len;
1064 ++ char *tmp;
1065 ++
1066 ++ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1067 ++
1068 ++ if (info == NULL || !cfg->twidth || !cfg->theight ||
1069 ++ cfg->tx + cfg->twidth > info->var.xres ||
1070 ++ cfg->ty + cfg->theight > info->var.yres)
1071 ++ return -EINVAL;
1072 ++
1073 ++ len = strlen_user(cfg->theme);
1074 ++ if (!len || len > FBCON_DECOR_THEME_LEN)
1075 ++ return -EINVAL;
1076 ++ tmp = kmalloc(len, GFP_KERNEL);
1077 ++ if (!tmp)
1078 ++ return -ENOMEM;
1079 ++ if (copy_from_user(tmp, (void __user *)cfg->theme, len))
1080 ++ return -EFAULT;
1081 ++ cfg->theme = tmp;
1082 ++ cfg->state = 0;
1083 ++
1084 ++ /* If this ioctl is a response to a request from kernel, the console sem
1085 ++ * is already held; we also don't need to disable decor because either the
1086 ++ * new config and background picture will be successfully loaded, and the
1087 ++ * decor will stay on, or in case of a failure it'll be turned off in fbcon. */
1088 ++ if (origin == FBCON_DECOR_IO_ORIG_USER) {
1089 ++ acquire_console_sem();
1090 ++ if (vc->vc_decor.state)
1091 ++ fbcon_decor_disable(vc, 1);
1092 ++ }
1093 ++
1094 ++ if (vc->vc_decor.theme)
1095 ++ kfree(vc->vc_decor.theme);
1096 ++
1097 ++ vc->vc_decor = *cfg;
1098 ++
1099 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1100 ++ release_console_sem();
1101 ++
1102 ++ printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n",
1103 ++ vc->vc_num, vc->vc_decor.theme);
1104 ++ return 0;
1105 ++}
1106 ++
1107 ++static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc, struct vc_decor *decor)
1108 ++{
1109 ++ char __user *tmp;
1110 ++
1111 ++ tmp = decor->theme;
1112 ++ *decor = vc->vc_decor;
1113 ++ decor->theme = tmp;
1114 ++
1115 ++ if (vc->vc_decor.theme) {
1116 ++ if (copy_to_user(tmp, vc->vc_decor.theme, strlen(vc->vc_decor.theme) + 1))
1117 ++ return -EFAULT;
1118 ++ } else
1119 ++ if (put_user(0, tmp))
1120 ++ return -EFAULT;
1121 ++
1122 ++ return 0;
1123 ++}
1124 ++
1125 ++static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img, unsigned char origin)
1126 ++{
1127 ++ struct fb_info *info;
1128 ++ int len;
1129 ++ u8 *tmp;
1130 ++
1131 ++ if (vc->vc_num != fg_console)
1132 ++ return -EINVAL;
1133 ++
1134 ++ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1135 ++
1136 ++ if (info == NULL)
1137 ++ return -EINVAL;
1138 ++
1139 ++ if (img->width != info->var.xres || img->height != info->var.yres) {
1140 ++ printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n");
1141 ++ printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height, info->var.xres, info->var.yres);
1142 ++ return -EINVAL;
1143 ++ }
1144 ++
1145 ++ if (img->depth != info->var.bits_per_pixel) {
1146 ++ printk(KERN_ERR "fbcondecor: picture depth mismatch\n");
1147 ++ return -EINVAL;
1148 ++ }
1149 ++
1150 ++ if (img->depth == 8) {
1151 ++ if (!img->cmap.len || !img->cmap.red || !img->cmap.green ||
1152 ++ !img->cmap.blue)
1153 ++ return -EINVAL;
1154 ++
1155 ++ tmp = vmalloc(img->cmap.len * 3 * 2);
1156 ++ if (!tmp)
1157 ++ return -ENOMEM;
1158 ++
1159 ++ if (copy_from_user(tmp,
1160 ++ (void __user*)img->cmap.red, (img->cmap.len << 1)) ||
1161 ++ copy_from_user(tmp + (img->cmap.len << 1),
1162 ++ (void __user*)img->cmap.green, (img->cmap.len << 1)) ||
1163 ++ copy_from_user(tmp + (img->cmap.len << 2),
1164 ++ (void __user*)img->cmap.blue, (img->cmap.len << 1))) {
1165 ++ vfree(tmp);
1166 ++ return -EFAULT;
1167 ++ }
1168 ++
1169 ++ img->cmap.transp = NULL;
1170 ++ img->cmap.red = (u16*)tmp;
1171 ++ img->cmap.green = img->cmap.red + img->cmap.len;
1172 ++ img->cmap.blue = img->cmap.green + img->cmap.len;
1173 ++ } else {
1174 ++ img->cmap.red = NULL;
1175 ++ }
1176 ++
1177 ++ len = ((img->depth + 7) >> 3) * img->width * img->height;
1178 ++
1179 ++ /*
1180 ++ * Allocate an additional byte so that we never go outside of the
1181 ++ * buffer boundaries in the rendering functions in a 24 bpp mode.
1182 ++ */
1183 ++ tmp = vmalloc(len + 1);
1184 ++
1185 ++ if (!tmp)
1186 ++ goto out;
1187 ++
1188 ++ if (copy_from_user(tmp, (void __user*)img->data, len))
1189 ++ goto out;
1190 ++
1191 ++ img->data = tmp;
1192 ++
1193 ++ /* If this ioctl is a response to a request from kernel, the console sem
1194 ++ * is already held. */
1195 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1196 ++ acquire_console_sem();
1197 ++
1198 ++ if (info->bgdecor.data)
1199 ++ vfree((u8*)info->bgdecor.data);
1200 ++ if (info->bgdecor.cmap.red)
1201 ++ vfree(info->bgdecor.cmap.red);
1202 ++
1203 ++ info->bgdecor = *img;
1204 ++
1205 ++ if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) {
1206 ++ redraw_screen(vc, 0);
1207 ++ update_region(vc, vc->vc_origin +
1208 ++ vc->vc_size_row * vc->vc_top,
1209 ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1210 ++ fbcon_decor_clear_margins(vc, info, 0);
1211 ++ }
1212 ++
1213 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1214 ++ release_console_sem();
1215 ++
1216 ++ return 0;
1217 ++
1218 ++out: if (img->cmap.red)
1219 ++ vfree(img->cmap.red);
1220 ++
1221 ++ if (tmp)
1222 ++ vfree(tmp);
1223 ++ return -ENOMEM;
1224 ++}
1225 ++
1226 ++static int fbcon_decor_ioctl(struct inode * inode, struct file *filp, u_int cmd,
1227 ++ u_long arg)
1228 ++{
1229 ++ struct fbcon_decor_iowrapper __user *wrapper = (void __user*) arg;
1230 ++ struct vc_data *vc = NULL;
1231 ++ unsigned short vc_num = 0;
1232 ++ unsigned char origin = 0;
1233 ++ void __user *data = NULL;
1234 ++
1235 ++ if (!access_ok(VERIFY_READ, wrapper,
1236 ++ sizeof(struct fbcon_decor_iowrapper)))
1237 ++ return -EFAULT;
1238 ++
1239 ++ __get_user(vc_num, &wrapper->vc);
1240 ++ __get_user(origin, &wrapper->origin);
1241 ++ __get_user(data, &wrapper->data);
1242 ++
1243 ++ if (!vc_cons_allocated(vc_num))
1244 ++ return -EINVAL;
1245 ++
1246 ++ vc = vc_cons[vc_num].d;
1247 ++
1248 ++ switch (cmd) {
1249 ++ case FBIOCONDECOR_SETPIC:
1250 ++ {
1251 ++ struct fb_image img;
1252 ++ if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image)))
1253 ++ return -EFAULT;
1254 ++
1255 ++ return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
1256 ++ }
1257 ++ case FBIOCONDECOR_SETCFG:
1258 ++ {
1259 ++ struct vc_decor cfg;
1260 ++ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
1261 ++ return -EFAULT;
1262 ++
1263 ++ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
1264 ++ }
1265 ++ case FBIOCONDECOR_GETCFG:
1266 ++ {
1267 ++ int rval;
1268 ++ struct vc_decor cfg;
1269 ++
1270 ++ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
1271 ++ return -EFAULT;
1272 ++
1273 ++ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
1274 ++
1275 ++ if (copy_to_user(data, &cfg, sizeof(struct vc_decor)))
1276 ++ return -EFAULT;
1277 ++ return rval;
1278 ++ }
1279 ++ case FBIOCONDECOR_SETSTATE:
1280 ++ {
1281 ++ unsigned int state = 0;
1282 ++ if (get_user(state, (unsigned int __user *)data))
1283 ++ return -EFAULT;
1284 ++ return fbcon_decor_ioctl_dosetstate(vc, state, origin);
1285 ++ }
1286 ++ case FBIOCONDECOR_GETSTATE:
1287 ++ {
1288 ++ unsigned int state = 0;
1289 ++ fbcon_decor_ioctl_dogetstate(vc, &state);
1290 ++ return put_user(state, (unsigned int __user *)data);
1291 ++ }
1292 ++
1293 ++ default:
1294 ++ return -ENOIOCTLCMD;
1295 ++ }
1296 ++}
1297 ++
1298 ++#ifdef CONFIG_COMPAT
1299 ++
1300 ++static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
1301 ++
1302 ++ struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg;
1303 ++ struct vc_data *vc = NULL;
1304 ++ unsigned short vc_num = 0;
1305 ++ unsigned char origin = 0;
1306 ++ compat_uptr_t data_compat = 0;
1307 ++ void __user *data = NULL;
1308 ++
1309 ++ if (!access_ok(VERIFY_READ, wrapper,
1310 ++ sizeof(struct fbcon_decor_iowrapper32)))
1311 ++ return -EFAULT;
1312 ++
1313 ++ __get_user(vc_num, &wrapper->vc);
1314 ++ __get_user(origin, &wrapper->origin);
1315 ++ __get_user(data_compat, &wrapper->data);
1316 ++ data = compat_ptr(data_compat);
1317 ++
1318 ++ if (!vc_cons_allocated(vc_num))
1319 ++ return -EINVAL;
1320 ++
1321 ++ vc = vc_cons[vc_num].d;
1322 ++
1323 ++ switch (cmd) {
1324 ++ case FBIOCONDECOR_SETPIC32:
1325 ++ {
1326 ++ struct fb_image32 img_compat;
1327 ++ struct fb_image img;
1328 ++
1329 ++ if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32)))
1330 ++ return -EFAULT;
1331 ++
1332 ++ fb_image_from_compat(img, img_compat);
1333 ++
1334 ++ return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
1335 ++ }
1336 ++
1337 ++ case FBIOCONDECOR_SETCFG32:
1338 ++ {
1339 ++ struct vc_decor32 cfg_compat;
1340 ++ struct vc_decor cfg;
1341 ++
1342 ++ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
1343 ++ return -EFAULT;
1344 ++
1345 ++ vc_decor_from_compat(cfg, cfg_compat);
1346 ++
1347 ++ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
1348 ++ }
1349 ++
1350 ++ case FBIOCONDECOR_GETCFG32:
1351 ++ {
1352 ++ int rval;
1353 ++ struct vc_decor32 cfg_compat;
1354 ++ struct vc_decor cfg;
1355 ++
1356 ++ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
1357 ++ return -EFAULT;
1358 ++ cfg.theme = compat_ptr(cfg_compat.theme);
1359 ++
1360 ++ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
1361 ++
1362 ++ vc_decor_to_compat(cfg_compat, cfg);
1363 ++
1364 ++ if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32)))
1365 ++ return -EFAULT;
1366 ++ return rval;
1367 ++ }
1368 ++
1369 ++ case FBIOCONDECOR_SETSTATE32:
1370 ++ {
1371 ++ compat_uint_t state_compat = 0;
1372 ++ unsigned int state = 0;
1373 ++
1374 ++ if (get_user(state_compat, (compat_uint_t __user *)data))
1375 ++ return -EFAULT;
1376 ++
1377 ++ state = (unsigned int)state_compat;
1378 ++
1379 ++ return fbcon_decor_ioctl_dosetstate(vc, state, origin);
1380 ++ }
1381 ++
1382 ++ case FBIOCONDECOR_GETSTATE32:
1383 ++ {
1384 ++ compat_uint_t state_compat = 0;
1385 ++ unsigned int state = 0;
1386 ++
1387 ++ fbcon_decor_ioctl_dogetstate(vc, &state);
1388 ++ state_compat = (compat_uint_t)state;
1389 ++
1390 ++ return put_user(state_compat, (compat_uint_t __user *)data);
1391 ++ }
1392 ++
1393 ++ default:
1394 ++ return -ENOIOCTLCMD;
1395 ++ }
1396 ++}
1397 ++#else
1398 ++ #define fbcon_decor_compat_ioctl NULL
1399 ++#endif
1400 ++
1401 ++static struct file_operations fbcon_decor_ops = {
1402 ++ .owner = THIS_MODULE,
1403 ++ .ioctl = fbcon_decor_ioctl,
1404 ++ .compat_ioctl = fbcon_decor_compat_ioctl
1405 ++};
1406 ++
1407 ++static struct miscdevice fbcon_decor_dev = {
1408 ++ .minor = MISC_DYNAMIC_MINOR,
1409 ++ .name = "fbcondecor",
1410 ++ .fops = &fbcon_decor_ops
1411 ++};
1412 ++
1413 ++void fbcon_decor_reset(void)
1414 ++{
1415 ++ struct fb_info *info;
1416 ++ struct vc_data *vc;
1417 ++ int i;
1418 ++
1419 ++ vc = vc_cons[0].d;
1420 ++ info = registered_fb[0];
1421 ++
1422 ++ for (i = 0; i < num_registered_fb; i++) {
1423 ++ registered_fb[i]->bgdecor.data = NULL;
1424 ++ registered_fb[i]->bgdecor.cmap.red = NULL;
1425 ++ }
1426 ++
1427 ++ for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
1428 ++ vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth =
1429 ++ vc_cons[i].d->vc_decor.theight = 0;
1430 ++ vc_cons[i].d->vc_decor.theme = NULL;
1431 ++ }
1432 ++
1433 ++ return;
1434 ++}
1435 ++
1436 ++int fbcon_decor_init(void)
1437 ++{
1438 ++ int i;
1439 ++
1440 ++ fbcon_decor_reset();
1441 ++
1442 ++ if (initialized)
1443 ++ return 0;
1444 ++
1445 ++ i = misc_register(&fbcon_decor_dev);
1446 ++ if (i) {
1447 ++ printk(KERN_ERR "fbcondecor: failed to register device\n");
1448 ++ return i;
1449 ++ }
1450 ++
1451 ++ fbcon_decor_call_helper("init", 0);
1452 ++ initialized = 1;
1453 ++ return 0;
1454 ++}
1455 ++
1456 ++int fbcon_decor_exit(void)
1457 ++{
1458 ++ fbcon_decor_reset();
1459 ++ return 0;
1460 ++}
1461 ++
1462 ++EXPORT_SYMBOL(fbcon_decor_path);
1463 +diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h
1464 +new file mode 100644
1465 +index 0000000..1d852dd
1466 +--- /dev/null
1467 ++++ b/drivers/video/console/fbcondecor.h
1468 +@@ -0,0 +1,78 @@
1469 ++/*
1470 ++ * linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers
1471 ++ *
1472 ++ * Copyright (C) 2004 Michal Januszewski <spock@g.o>
1473 ++ *
1474 ++ */
1475 ++
1476 ++#ifndef __FBCON_DECOR_H
1477 ++#define __FBCON_DECOR_H
1478 ++
1479 ++#ifndef _LINUX_FB_H
1480 ++#include <linux/fb.h>
1481 ++#endif
1482 ++
1483 ++/* This is needed for vc_cons in fbcmap.c */
1484 ++#include <linux/vt_kern.h>
1485 ++
1486 ++struct fb_cursor;
1487 ++struct fb_info;
1488 ++struct vc_data;
1489 ++
1490 ++#ifdef CONFIG_FB_CON_DECOR
1491 ++/* fbcondecor.c */
1492 ++int fbcon_decor_init(void);
1493 ++int fbcon_decor_exit(void);
1494 ++int fbcon_decor_call_helper(char* cmd, unsigned short cons);
1495 ++int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw);
1496 ++
1497 ++/* cfbcondecor.c */
1498 ++void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
1499 ++void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor);
1500 ++void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
1501 ++void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
1502 ++void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank);
1503 ++void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
1504 ++void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
1505 ++void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
1506 ++
1507 ++/* vt.c */
1508 ++void acquire_console_sem(void);
1509 ++void release_console_sem(void);
1510 ++void do_unblank_screen(int entering_gfx);
1511 ++
1512 ++/* struct vc_data *y */
1513 ++#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme)
1514 ++
1515 ++/* struct fb_info *x, struct vc_data *y */
1516 ++#define fbcon_decor_active_nores(x,y) (x->bgdecor.data && fbcon_decor_active_vc(y))
1517 ++
1518 ++/* struct fb_info *x, struct vc_data *y */
1519 ++#define fbcon_decor_active(x,y) (fbcon_decor_active_nores(x,y) && \
1520 ++ x->bgdecor.width == x->var.xres && \
1521 ++ x->bgdecor.height == x->var.yres && \
1522 ++ x->bgdecor.depth == x->var.bits_per_pixel)
1523 ++
1524 ++
1525 ++#else /* CONFIG_FB_CON_DECOR */
1526 ++
1527 ++static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
1528 ++static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
1529 ++static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
1530 ++static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
1531 ++static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
1532 ++static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
1533 ++static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
1534 ++static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
1535 ++static inline int fbcon_decor_call_helper(char* cmd, unsigned short cons) { return 0; }
1536 ++static inline int fbcon_decor_init(void) { return 0; }
1537 ++static inline int fbcon_decor_exit(void) { return 0; }
1538 ++static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
1539 ++
1540 ++#define fbcon_decor_active_vc(y) (0)
1541 ++#define fbcon_decor_active_nores(x,y) (0)
1542 ++#define fbcon_decor_active(x,y) (0)
1543 ++
1544 ++#endif /* CONFIG_FB_CON_DECOR */
1545 ++
1546 ++#endif /* __FBCON_DECOR_H */
1547 +diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
1548 +index f53b9f1..467f921 100644
1549 +--- a/drivers/video/fbcmap.c
1550 ++++ b/drivers/video/fbcmap.c
1551 +@@ -17,6 +17,8 @@
1552 + #include <linux/slab.h>
1553 + #include <linux/uaccess.h>
1554 +
1555 ++#include "console/fbcondecor.h"
1556 ++
1557 + static u16 red2[] __read_mostly = {
1558 + 0x0000, 0xaaaa
1559 + };
1560 +@@ -234,14 +236,17 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
1561 + if (transp)
1562 + htransp = *transp++;
1563 + if (info->fbops->fb_setcolreg(start++,
1564 +- hred, hgreen, hblue,
1565 ++ hred, hgreen, hblue,
1566 + htransp, info))
1567 + break;
1568 + }
1569 + }
1570 +- if (rc == 0)
1571 ++ if (rc == 0) {
1572 + fb_copy_cmap(cmap, &info->cmap);
1573 +-
1574 ++ if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
1575 ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR)
1576 ++ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
1577 ++ }
1578 + return rc;
1579 + }
1580 +
1581 +diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
1582 +index a85c818..1f1c24b 100644
1583 +--- a/drivers/video/fbmem.c
1584 ++++ b/drivers/video/fbmem.c
1585 +@@ -1173,15 +1173,6 @@ struct fb_fix_screeninfo32 {
1586 + u16 reserved[3];
1587 + };
1588 +
1589 +-struct fb_cmap32 {
1590 +- u32 start;
1591 +- u32 len;
1592 +- compat_caddr_t red;
1593 +- compat_caddr_t green;
1594 +- compat_caddr_t blue;
1595 +- compat_caddr_t transp;
1596 +-};
1597 +-
1598 + static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1599 + unsigned long arg)
1600 + {
1601 +diff --git a/include/linux/console_decor.h b/include/linux/console_decor.h
1602 +new file mode 100644
1603 +index 0000000..04b8d80
1604 +--- /dev/null
1605 ++++ b/include/linux/console_decor.h
1606 +@@ -0,0 +1,46 @@
1607 ++#ifndef _LINUX_CONSOLE_DECOR_H_
1608 ++#define _LINUX_CONSOLE_DECOR_H_ 1
1609 ++
1610 ++/* A structure used by the framebuffer console decorations (drivers/video/console/fbcondecor.c) */
1611 ++struct vc_decor {
1612 ++ __u8 bg_color; /* The color that is to be treated as transparent */
1613 ++ __u8 state; /* Current decor state: 0 = off, 1 = on */
1614 ++ __u16 tx, ty; /* Top left corner coordinates of the text field */
1615 ++ __u16 twidth, theight; /* Width and height of the text field */
1616 ++ char* theme;
1617 ++};
1618 ++
1619 ++#ifdef __KERNEL__
1620 ++#ifdef CONFIG_COMPAT
1621 ++#include <linux/compat.h>
1622 ++
1623 ++struct vc_decor32 {
1624 ++ __u8 bg_color; /* The color that is to be treated as transparent */
1625 ++ __u8 state; /* Current decor state: 0 = off, 1 = on */
1626 ++ __u16 tx, ty; /* Top left corner coordinates of the text field */
1627 ++ __u16 twidth, theight; /* Width and height of the text field */
1628 ++ compat_uptr_t theme;
1629 ++};
1630 ++
1631 ++#define vc_decor_from_compat(to, from) \
1632 ++ (to).bg_color = (from).bg_color; \
1633 ++ (to).state = (from).state; \
1634 ++ (to).tx = (from).tx; \
1635 ++ (to).ty = (from).ty; \
1636 ++ (to).twidth = (from).twidth; \
1637 ++ (to).theight = (from).theight; \
1638 ++ (to).theme = compat_ptr((from).theme)
1639 ++
1640 ++#define vc_decor_to_compat(to, from) \
1641 ++ (to).bg_color = (from).bg_color; \
1642 ++ (to).state = (from).state; \
1643 ++ (to).tx = (from).tx; \
1644 ++ (to).ty = (from).ty; \
1645 ++ (to).twidth = (from).twidth; \
1646 ++ (to).theight = (from).theight; \
1647 ++ (to).theme = ptr_to_compat((from).theme)
1648 ++
1649 ++#endif /* CONFIG_COMPAT */
1650 ++#endif /* __KERNEL__ */
1651 ++
1652 ++#endif
1653 +diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
1654 +index 38fe59d..8e4058b 100644
1655 +--- a/include/linux/console_struct.h
1656 ++++ b/include/linux/console_struct.h
1657 +@@ -19,6 +19,7 @@
1658 + struct vt_struct;
1659 +
1660 + #define NPAR 16
1661 ++#include <linux/console_decor.h>
1662 +
1663 + struct vc_data {
1664 + unsigned short vc_num; /* Console number */
1665 +@@ -105,6 +106,8 @@ struct vc_data {
1666 + struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */
1667 + unsigned long vc_uni_pagedir;
1668 + unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
1669 ++
1670 ++ struct vc_decor vc_decor;
1671 + /* additional information is in vt_kern.h */
1672 + };
1673 +
1674 +diff --git a/include/linux/fb.h b/include/linux/fb.h
1675 +index f847df9..7ac118e 100644
1676 +--- a/include/linux/fb.h
1677 ++++ b/include/linux/fb.h
1678 +@@ -3,13 +3,31 @@
1679 +
1680 + #include <linux/types.h>
1681 + #include <linux/i2c.h>
1682 +-
1683 + struct dentry;
1684 +
1685 + /* Definitions of frame buffers */
1686 +
1687 + #define FB_MAX 32 /* sufficient for now */
1688 +
1689 ++struct fbcon_decor_iowrapper
1690 ++{
1691 ++ unsigned short vc; /* Virtual console */
1692 ++ unsigned char origin; /* Point of origin of the request */
1693 ++ void *data;
1694 ++};
1695 ++
1696 ++#ifdef __KERNEL__
1697 ++#ifdef CONFIG_COMPAT
1698 ++#include <linux/compat.h>
1699 ++struct fbcon_decor_iowrapper32
1700 ++{
1701 ++ unsigned short vc; /* Virtual console */
1702 ++ unsigned char origin; /* Point of origin of the request */
1703 ++ compat_uptr_t data;
1704 ++};
1705 ++#endif /* CONFIG_COMPAT */
1706 ++#endif /* __KERNEL__ */
1707 ++
1708 + /* ioctls
1709 + 0x46 is 'F' */
1710 + #define FBIOGET_VSCREENINFO 0x4600
1711 +@@ -37,7 +55,24 @@ struct dentry;
1712 + #define FBIOGET_HWCINFO 0x4616
1713 + #define FBIOPUT_MODEINFO 0x4617
1714 + #define FBIOGET_DISPINFO 0x4618
1715 ++#define FBIOCONDECOR_SETCFG _IOWR('F', 0x19, struct fbcon_decor_iowrapper)
1716 ++#define FBIOCONDECOR_GETCFG _IOR('F', 0x1A, struct fbcon_decor_iowrapper)
1717 ++#define FBIOCONDECOR_SETSTATE _IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
1718 ++#define FBIOCONDECOR_GETSTATE _IOR('F', 0x1C, struct fbcon_decor_iowrapper)
1719 ++#define FBIOCONDECOR_SETPIC _IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
1720 ++#ifdef __KERNEL__
1721 ++#ifdef CONFIG_COMPAT
1722 ++#define FBIOCONDECOR_SETCFG32 _IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
1723 ++#define FBIOCONDECOR_GETCFG32 _IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
1724 ++#define FBIOCONDECOR_SETSTATE32 _IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
1725 ++#define FBIOCONDECOR_GETSTATE32 _IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
1726 ++#define FBIOCONDECOR_SETPIC32 _IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
1727 ++#endif /* CONFIG_COMPAT */
1728 ++#endif /* __KERNEL__ */
1729 +
1730 ++#define FBCON_DECOR_THEME_LEN 128 /* Maximum lenght of a theme name */
1731 ++#define FBCON_DECOR_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */
1732 ++#define FBCON_DECOR_IO_ORIG_USER 1 /* User ioctl origin */
1733 +
1734 + #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
1735 + #define FB_TYPE_PLANES 1 /* Non interleaved planes */
1736 +@@ -281,6 +316,28 @@ struct fb_cmap {
1737 + __u16 *transp; /* transparency, can be NULL */
1738 + };
1739 +
1740 ++#ifdef __KERNEL__
1741 ++#ifdef CONFIG_COMPAT
1742 ++struct fb_cmap32 {
1743 ++ __u32 start;
1744 ++ __u32 len; /* Number of entries */
1745 ++ compat_uptr_t red; /* Red values */
1746 ++ compat_uptr_t green;
1747 ++ compat_uptr_t blue;
1748 ++ compat_uptr_t transp; /* transparency, can be NULL */
1749 ++};
1750 ++
1751 ++#define fb_cmap_from_compat(to, from) \
1752 ++ (to).start = (from).start; \
1753 ++ (to).len = (from).len; \
1754 ++ (to).red = compat_ptr((from).red); \
1755 ++ (to).green = compat_ptr((from).green); \
1756 ++ (to).blue = compat_ptr((from).blue); \
1757 ++ (to).transp = compat_ptr((from).transp)
1758 ++
1759 ++#endif /* CONFIG_COMPAT */
1760 ++#endif /* __KERNEL__ */
1761 ++
1762 + struct fb_con2fbmap {
1763 + __u32 console;
1764 + __u32 framebuffer;
1765 +@@ -362,6 +419,34 @@ struct fb_image {
1766 + struct fb_cmap cmap; /* color map info */
1767 + };
1768 +
1769 ++#ifdef __KERNEL__
1770 ++#ifdef CONFIG_COMPAT
1771 ++struct fb_image32 {
1772 ++ __u32 dx; /* Where to place image */
1773 ++ __u32 dy;
1774 ++ __u32 width; /* Size of image */
1775 ++ __u32 height;
1776 ++ __u32 fg_color; /* Only used when a mono bitmap */
1777 ++ __u32 bg_color;
1778 ++ __u8 depth; /* Depth of the image */
1779 ++ const compat_uptr_t data; /* Pointer to image data */
1780 ++ struct fb_cmap32 cmap; /* color map info */
1781 ++};
1782 ++
1783 ++#define fb_image_from_compat(to, from) \
1784 ++ (to).dx = (from).dx; \
1785 ++ (to).dy = (from).dy; \
1786 ++ (to).width = (from).width; \
1787 ++ (to).height = (from).height; \
1788 ++ (to).fg_color = (from).fg_color; \
1789 ++ (to).bg_color = (from).bg_color; \
1790 ++ (to).depth = (from).depth; \
1791 ++ (to).data = compat_ptr((from).data); \
1792 ++ fb_cmap_from_compat((to).cmap, (from).cmap)
1793 ++
1794 ++#endif /* CONFIG_COMPAT */
1795 ++#endif /* __KERNEL__ */
1796 ++
1797 + /*
1798 + * hardware cursor control
1799 + */
1800 +@@ -859,6 +944,9 @@ struct fb_info {
1801 + #define FBINFO_STATE_SUSPENDED 1
1802 + u32 state; /* Hardware state i.e suspend */
1803 + void *fbcon_par; /* fbcon use-only private area */
1804 ++
1805 ++ struct fb_image bgdecor;
1806 ++
1807 + /* From here on everything is device dependent */
1808 + void *par;
1809 + /* we need the PCI or similiar aperture base/size not
1810 +diff --git a/kernel/sysctl.c b/kernel/sysctl.c
1811 +index 98e0232..24f4e31 100644
1812 +--- a/kernel/sysctl.c
1813 ++++ b/kernel/sysctl.c
1814 +@@ -118,6 +118,9 @@ static int ngroups_max = NGROUPS_MAX;
1815 + extern char modprobe_path[];
1816 + extern int modules_disabled;
1817 + #endif
1818 ++#ifdef CONFIG_FB_CON_DECOR
1819 ++extern char fbcon_decor_path[];
1820 ++#endif
1821 + #ifdef CONFIG_CHR_DEV_SG
1822 + extern int sg_big_buff;
1823 + #endif
1824 +@@ -230,6 +233,18 @@ static struct ctl_table root_table[] = {
1825 + .mode = 0555,
1826 + .child = dev_table,
1827 + },
1828 ++#ifdef CONFIG_FB_CON_DECOR
1829 ++ {
1830 ++ .ctl_name = CTL_UNNUMBERED,
1831 ++ .procname = "fbcondecor",
1832 ++ .data = &fbcon_decor_path,
1833 ++ .maxlen = KMOD_PATH_LEN,
1834 ++ .mode = 0644,
1835 ++ .proc_handler = &proc_dostring,
1836 ++ .strategy = &sysctl_string,
1837 ++ },
1838 ++#endif
1839 ++
1840 + /*
1841 + * NOTE: do not add new entries to this table unless you have read
1842 + * Documentation/sysctl/ctl_unnumbered.txt
1843 +--- a/drivers/video/console/fbcon.c 2009-10-07 20:24:23.000000000 -0400
1844 ++++ b/drivers/video/console/fbcon.c 2009-10-07 20:23:26.000000000 -0400
1845 +@@ -80,6 +80,7 @@
1846 + #include <asm/system.h>
1847 +
1848 + #include "fbcon.h"
1849 ++#include "fbcondecor.h"
1850 +
1851 + #ifdef FBCONDEBUG
1852 + # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
1853 +@@ -95,7 +96,7 @@ enum {
1854 +
1855 + static struct display fb_display[MAX_NR_CONSOLES];
1856 +
1857 +-static signed char con2fb_map[MAX_NR_CONSOLES];
1858 ++signed char con2fb_map[MAX_NR_CONSOLES];
1859 + static signed char con2fb_map_boot[MAX_NR_CONSOLES];
1860 +
1861 + static int logo_lines;
1862 +@@ -286,7 +287,7 @@ static inline int fbcon_is_inactive(stru
1863 + vc->vc_mode != KD_TEXT || ops->graphics);
1864 + }
1865 +
1866 +-static inline int get_color(struct vc_data *vc, struct fb_info *info,
1867 ++inline int get_color(struct vc_data *vc, struct fb_info *info,
1868 + u16 c, int is_fg)
1869 + {
1870 + int depth = fb_get_color_depth(&info->var, &info->fix);
1871 +@@ -391,6 +392,7 @@ static void fb_flashcursor(struct work_s
1872 + CM_ERASE : CM_DRAW;
1873 + ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
1874 + get_color(vc, info, c, 0));
1875 ++
1876 + release_console_sem();
1877 + }
1878 +
1879 +@@ -527,6 +529,7 @@ static int search_for_mapped_con(void)
1880 + static int fbcon_takeover(int show_logo)
1881 + {
1882 + int err, i;
1883 ++ struct fb_info *info;
1884 +
1885 + if (!num_registered_fb)
1886 + return -ENODEV;
1887 +@@ -540,6 +543,8 @@ static int fbcon_takeover(int show_logo)
1888 + err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,
1889 + fbcon_is_default);
1890 +
1891 ++ info = registered_fb[info_idx];
1892 ++
1893 + if (err) {
1894 + for (i = first_fb_vc; i <= last_fb_vc; i++) {
1895 + con2fb_map[i] = -1;
1896 +@@ -547,6 +552,9 @@ static int fbcon_takeover(int show_logo)
1897 + info_idx = -1;
1898 + } else {
1899 + fbcon_has_console_bind = 1;
1900 ++ unlock_fb_info(info);
1901 ++ fbcon_decor_init();
1902 ++ lock_fb_info(info);
1903 + }
1904 +
1905 + return err;
1906 +@@ -988,6 +996,12 @@ static const char *fbcon_startup(void)
1907 + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1908 + cols /= vc->vc_font.width;
1909 + rows /= vc->vc_font.height;
1910 ++
1911 ++ if (fbcon_decor_active(info, vc)) {
1912 ++ cols = vc->vc_decor.twidth / vc->vc_font.width;
1913 ++ rows = vc->vc_decor.theight / vc->vc_font.height;
1914 ++ }
1915 ++
1916 + vc_resize(vc, cols, rows);
1917 +
1918 + DPRINTK("mode: %s\n", info->fix.id);
1919 +@@ -1017,7 +1031,7 @@ static void fbcon_init(struct vc_data *v
1920 + cap = info->flags;
1921 +
1922 + if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1923 +- (info->fix.type == FB_TYPE_TEXT))
1924 ++ (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
1925 + logo = 0;
1926 +
1927 + if (var_to_display(p, &info->var, info))
1928 +@@ -1219,6 +1233,11 @@ static void fbcon_clear(struct vc_data *
1929 + if (sy < vc->vc_top && vc->vc_top == logo_lines)
1930 + vc->vc_top = 0;
1931 +
1932 ++ if (fbcon_decor_active(info, vc)) {
1933 ++ fbcon_decor_clear(vc, info, sy, sx, height, width);
1934 ++ return;
1935 ++ }
1936 ++
1937 + /* Split blits that cross physical y_wrap boundary */
1938 +
1939 + y_break = p->vrows - p->yscroll;
1940 +@@ -1238,10 +1257,15 @@ static void fbcon_putcs(struct vc_data *
1941 + struct display *p = &fb_display[vc->vc_num];
1942 + struct fbcon_ops *ops = info->fbcon_par;
1943 +
1944 +- if (!fbcon_is_inactive(vc, info))
1945 +- ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1946 +- get_color(vc, info, scr_readw(s), 1),
1947 +- get_color(vc, info, scr_readw(s), 0));
1948 ++ if (!fbcon_is_inactive(vc, info)) {
1949 ++
1950 ++ if (fbcon_decor_active(info, vc))
1951 ++ fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
1952 ++ else
1953 ++ ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1954 ++ get_color(vc, info, scr_readw(s), 1),
1955 ++ get_color(vc, info, scr_readw(s), 0));
1956 ++ }
1957 + }
1958 +
1959 + static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
1960 +@@ -1257,8 +1281,13 @@ static void fbcon_clear_margins(struct v
1961 + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1962 + struct fbcon_ops *ops = info->fbcon_par;
1963 +
1964 +- if (!fbcon_is_inactive(vc, info))
1965 +- ops->clear_margins(vc, info, bottom_only);
1966 ++ if (!fbcon_is_inactive(vc, info)) {
1967 ++ if (fbcon_decor_active(info, vc)) {
1968 ++ fbcon_decor_clear_margins(vc, info, bottom_only);
1969 ++ } else {
1970 ++ ops->clear_margins(vc, info, bottom_only);
1971 ++ }
1972 ++ }
1973 + }
1974 +
1975 + static void fbcon_cursor(struct vc_data *vc, int mode)
1976 +@@ -1778,7 +1807,7 @@ static int fbcon_scroll(struct vc_data *
1977 + count = vc->vc_rows;
1978 + if (softback_top)
1979 + fbcon_softback_note(vc, t, count);
1980 +- if (logo_shown >= 0)
1981 ++ if (logo_shown >= 0 || fbcon_decor_active(info, vc))
1982 + goto redraw_up;
1983 + switch (p->scrollmode) {
1984 + case SCROLL_MOVE:
1985 +@@ -1871,6 +1900,8 @@ static int fbcon_scroll(struct vc_data *
1986 + count = vc->vc_rows;
1987 + if (logo_shown >= 0)
1988 + goto redraw_down;
1989 ++ if (fbcon_decor_active(info, vc))
1990 ++ goto redraw_down;
1991 + switch (p->scrollmode) {
1992 + case SCROLL_MOVE:
1993 + fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
1994 +@@ -2019,6 +2050,13 @@ static void fbcon_bmove_rec(struct vc_da
1995 + }
1996 + return;
1997 + }
1998 ++
1999 ++ if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
2000 ++ /* must use slower redraw bmove to keep background pic intact */
2001 ++ fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
2002 ++ return;
2003 ++ }
2004 ++
2005 + ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2006 + height, width);
2007 + }
2008 +@@ -2089,8 +2127,8 @@ static int fbcon_resize(struct vc_data *
2009 + var.yres = virt_h * virt_fh;
2010 + x_diff = info->var.xres - var.xres;
2011 + y_diff = info->var.yres - var.yres;
2012 +- if (x_diff < 0 || x_diff > virt_fw ||
2013 +- y_diff < 0 || y_diff > virt_fh) {
2014 ++ if ((x_diff < 0 || x_diff > virt_fw ||
2015 ++ y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
2016 + const struct fb_videomode *mode;
2017 +
2018 + DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
2019 +@@ -2126,6 +2164,19 @@ static int fbcon_switch(struct vc_data *
2020 +
2021 + info = registered_fb[con2fb_map[vc->vc_num]];
2022 + ops = info->fbcon_par;
2023 ++ prev_console = ops->currcon;
2024 ++ if (prev_console != -1)
2025 ++ old_info = registered_fb[con2fb_map[prev_console]];
2026 ++
2027 ++ if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2028 ++ struct vc_data *vc_curr = vc_cons[prev_console].d;
2029 ++ if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
2030 ++ /* Clear the screen to avoid displaying funky colors during
2031 ++ * palette updates. */
2032 ++ memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset,
2033 ++ 0, info->var.yres * info->fix.line_length);
2034 ++ }
2035 ++ }
2036 +
2037 + if (softback_top) {
2038 + if (softback_lines)
2039 +@@ -2144,9 +2195,6 @@ static int fbcon_switch(struct vc_data *
2040 + logo_shown = FBCON_LOGO_CANSHOW;
2041 + }
2042 +
2043 +- prev_console = ops->currcon;
2044 +- if (prev_console != -1)
2045 +- old_info = registered_fb[con2fb_map[prev_console]];
2046 + /*
2047 + * FIXME: If we have multiple fbdev's loaded, we need to
2048 + * update all info->currcon. Perhaps, we can place this
2049 +@@ -2184,6 +2232,18 @@ static int fbcon_switch(struct vc_data *
2050 + fbcon_del_cursor_timer(old_info);
2051 + }
2052 +
2053 ++ if (fbcon_decor_active_vc(vc)) {
2054 ++ struct vc_data *vc_curr = vc_cons[prev_console].d;
2055 ++
2056 ++ if (!vc_curr->vc_decor.theme ||
2057 ++ strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
2058 ++ (fbcon_decor_active_nores(info, vc_curr) &&
2059 ++ !fbcon_decor_active(info, vc_curr))) {
2060 ++ if (fbcon_decor_call_helper("modechange", vc->vc_num))
2061 ++ fbcon_decor_disable(vc, 0);
2062 ++ }
2063 ++ }
2064 ++
2065 + if (fbcon_is_inactive(vc, info) ||
2066 + ops->blank_state != FB_BLANK_UNBLANK)
2067 + fbcon_del_cursor_timer(info);
2068 +@@ -2295,15 +2355,20 @@ static int fbcon_blank(struct vc_data *v
2069 + info->fbops->fb_restore_state(info);
2070 + }
2071 +
2072 +- if (!fbcon_is_inactive(vc, info)) {
2073 ++ if (!fbcon_is_inactive(vc, info)) {
2074 + if (ops->blank_state != blank) {
2075 + ops->blank_state = blank;
2076 + fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2077 + ops->cursor_flash = (!blank);
2078 +
2079 +- if (!(info->flags & FBINFO_MISC_USEREVENT))
2080 +- if (fb_blank(info, blank))
2081 +- fbcon_generic_blank(vc, info, blank);
2082 ++ if (!(info->flags & FBINFO_MISC_USEREVENT)) {
2083 ++ if (fb_blank(info, blank)) {
2084 ++ if (fbcon_decor_active(info, vc))
2085 ++ fbcon_decor_blank(vc, info, blank);
2086 ++ else
2087 ++ fbcon_generic_blank(vc, info, blank);
2088 ++ }
2089 ++ }
2090 + }
2091 +
2092 + if (!blank)
2093 +@@ -2454,13 +2519,22 @@ static int fbcon_do_set_font(struct vc_d
2094 + }
2095 +
2096 + if (resize) {
2097 ++ /* reset wrap/pan */
2098 + int cols, rows;
2099 +
2100 + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2101 + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2102 ++
2103 ++ info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2104 ++ if (fbcon_decor_active(info, vc)) {
2105 ++ cols = vc->vc_decor.twidth;
2106 ++ rows = vc->vc_decor.theight;
2107 ++ }
2108 + cols /= w;
2109 + rows /= h;
2110 ++
2111 + vc_resize(vc, cols, rows);
2112 ++
2113 + if (CON_IS_VISIBLE(vc) && softback_buf)
2114 + fbcon_update_softback(vc);
2115 + } else if (CON_IS_VISIBLE(vc)
2116 +@@ -2589,7 +2663,7 @@ static int fbcon_set_palette(struct vc_d
2117 + int i, j, k, depth;
2118 + u8 val;
2119 +
2120 +- if (fbcon_is_inactive(vc, info))
2121 ++ if (fbcon_is_inactive(vc, info) || vc->vc_num != fg_console)
2122 + return -EINVAL;
2123 +
2124 + if (!CON_IS_VISIBLE(vc))
2125 +@@ -2615,7 +2689,49 @@ static int fbcon_set_palette(struct vc_d
2126 + } else
2127 + fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2128 +
2129 +- return fb_set_cmap(&palette_cmap, info);
2130 ++ if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2131 ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2132 ++
2133 ++ u16 *red, *green, *blue;
2134 ++ int minlen = min(min(info->var.red.length, info->var.green.length),
2135 ++ info->var.blue.length);
2136 ++ int h;
2137 ++
2138 ++ struct fb_cmap cmap = {
2139 ++ .start = 0,
2140 ++ .len = (1 << minlen),
2141 ++ .red = NULL,
2142 ++ .green = NULL,
2143 ++ .blue = NULL,
2144 ++ .transp = NULL
2145 ++ };
2146 ++
2147 ++ red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
2148 ++
2149 ++ if (!red)
2150 ++ goto out;
2151 ++
2152 ++ green = red + 256;
2153 ++ blue = green + 256;
2154 ++ cmap.red = red;
2155 ++ cmap.green = green;
2156 ++ cmap.blue = blue;
2157 ++
2158 ++ for (i = 0; i < cmap.len; i++) {
2159 ++ red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
2160 ++ }
2161 ++
2162 ++ h = fb_set_cmap(&cmap, info);
2163 ++ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
2164 ++ kfree(red);
2165 ++
2166 ++ return h;
2167 ++
2168 ++ } else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2169 ++ info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
2170 ++ fb_set_cmap(&info->bgdecor.cmap, info);
2171 ++
2172 ++out: return fb_set_cmap(&palette_cmap, info);
2173 + }
2174 +
2175 + static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
2176 +@@ -2841,7 +2957,18 @@ static void fbcon_modechanged(struct fb_
2177 + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2178 + cols /= vc->vc_font.width;
2179 + rows /= vc->vc_font.height;
2180 +- vc_resize(vc, cols, rows);
2181 ++
2182 ++ if (!fbcon_decor_active_nores(info, vc)) {
2183 ++ vc_resize(vc, cols, rows);
2184 ++ } else {
2185 ++ /* HACK: Do this properly at some point.. */
2186 ++ unlock_fb_info(info);
2187 ++ int res = fbcon_decor_call_helper("modechange", vc->vc_num);
2188 ++ lock_fb_info(info);
2189 ++ if (res)
2190 ++ fbcon_decor_disable(vc, 0);
2191 ++ }
2192 ++
2193 + updatescrollmode(p, info, vc);
2194 + scrollback_max = 0;
2195 + scrollback_current = 0;
2196 +@@ -3475,6 +3602,7 @@ static void fbcon_exit(void)
2197 + }
2198 + }
2199 +
2200 ++ fbcon_decor_exit();
2201 + fbcon_has_exited = 1;
2202 + }
2203 +
2204
2205 Deleted: genpatches-2.6/trunk/2.6.31/4202_fbcondecor-0.9.6.patch
2206 ===================================================================
2207 --- genpatches-2.6/trunk/2.6.31/4202_fbcondecor-0.9.6.patch 2009-10-06 15:22:02 UTC (rev 1617)
2208 +++ genpatches-2.6/trunk/2.6.31/4202_fbcondecor-0.9.6.patch 2009-10-08 01:20:56 UTC (rev 1618)
2209 @@ -1,2131 +0,0 @@
2210 -diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
2211 -index a618fd9..6eb4dc4 100644
2212 ---- a/Documentation/fb/00-INDEX
2213 -+++ b/Documentation/fb/00-INDEX
2214 -@@ -15,6 +15,8 @@ deferred_io.txt
2215 - - an introduction to deferred IO.
2216 - fbcon.txt
2217 - - intro to and usage guide for the framebuffer console (fbcon).
2218 -+fbcondecor.txt
2219 -+ - info on the Framebuffer Console Decoration
2220 - framebuffer.txt
2221 - - introduction to frame buffer devices.
2222 - imacfb.txt
2223 -diff --git a/Documentation/fb/fbcondecor.txt b/Documentation/fb/fbcondecor.txt
2224 -new file mode 100644
2225 -index 0000000..15889f3
2226 ---- /dev/null
2227 -+++ b/Documentation/fb/fbcondecor.txt
2228 -@@ -0,0 +1,207 @@
2229 -+What is it?
2230 -+-----------
2231 -+
2232 -+The framebuffer decorations are a kernel feature which allows displaying a
2233 -+background picture on selected consoles.
2234 -+
2235 -+What do I need to get it to work?
2236 -+---------------------------------
2237 -+
2238 -+To get fbcondecor up-and-running you will have to:
2239 -+ 1) get a copy of splashutils [1] or a similar program
2240 -+ 2) get some fbcondecor themes
2241 -+ 3) build the kernel helper program
2242 -+ 4) build your kernel with the FB_CON_DECOR option enabled.
2243 -+
2244 -+To get fbcondecor operational right after fbcon initialization is finished, you
2245 -+will have to include a theme and the kernel helper into your initramfs image.
2246 -+Please refer to splashutils documentation for instructions on how to do that.
2247 -+
2248 -+[1] The splashutils package can be downloaded from:
2249 -+ http://dev.gentoo.org/~spock/projects/splashutils/
2250 -+
2251 -+The userspace helper
2252 -+--------------------
2253 -+
2254 -+The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the
2255 -+kernel whenever an important event occurs and the kernel needs some kind of
2256 -+job to be carried out. Important events include console switches and video
2257 -+mode switches (the kernel requests background images and configuration
2258 -+parameters for the current console). The fbcondecor helper must be accessible at
2259 -+all times. If it's not, fbcondecor will be switched off automatically.
2260 -+
2261 -+It's possible to set path to the fbcondecor helper by writing it to
2262 -+/proc/sys/kernel/fbcondecor.
2263 -+
2264 -+*****************************************************************************
2265 -+
2266 -+The information below is mostly technical stuff. There's probably no need to
2267 -+read it unless you plan to develop a userspace helper.
2268 -+
2269 -+The fbcondecor protocol
2270 -+-----------------------
2271 -+
2272 -+The fbcondecor protocol defines a communication interface between the kernel and
2273 -+the userspace fbcondecor helper.
2274 -+
2275 -+The kernel side is responsible for:
2276 -+
2277 -+ * rendering console text, using an image as a background (instead of a
2278 -+ standard solid color fbcon uses),
2279 -+ * accepting commands from the user via ioctls on the fbcondecor device,
2280 -+ * calling the userspace helper to set things up as soon as the fb subsystem
2281 -+ is initialized.
2282 -+
2283 -+The userspace helper is responsible for everything else, including parsing
2284 -+configuration files, decompressing the image files whenever the kernel needs
2285 -+it, and communicating with the kernel if necessary.
2286 -+
2287 -+The fbcondecor protocol specifies how communication is done in both ways:
2288 -+kernel->userspace and userspace->helper.
2289 -+
2290 -+Kernel -> Userspace
2291 -+-------------------
2292 -+
2293 -+The kernel communicates with the userspace helper by calling it and specifying
2294 -+the task to be done in a series of arguments.
2295 -+
2296 -+The arguments follow the pattern:
2297 -+<fbcondecor protocol version> <command> <parameters>
2298 -+
2299 -+All commands defined in fbcondecor protocol v2 have the following parameters:
2300 -+ virtual console
2301 -+ framebuffer number
2302 -+ theme
2303 -+
2304 -+Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the
2305 -+framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used.
2306 -+
2307 -+Fbcondecor protocol v2 specifies the following commands:
2308 -+
2309 -+getpic
2310 -+------
2311 -+ The kernel issues this command to request image data. It's up to the
2312 -+ userspace helper to find a background image appropriate for the specified
2313 -+ theme and the current resolution. The userspace helper should respond by
2314 -+ issuing the FBIOCONDECOR_SETPIC ioctl.
2315 -+
2316 -+init
2317 -+----
2318 -+ The kernel issues this command after the fbcondecor device is created and
2319 -+ the fbcondecor interface is initialized. Upon receiving 'init', the userspace
2320 -+ helper should parse the kernel command line (/proc/cmdline) or otherwise
2321 -+ decide whether fbcondecor is to be activated.
2322 -+
2323 -+ To activate fbcondecor on the first console the helper should issue the
2324 -+ FBIOCONDECOR_SETCFG, FBIOCONDECOR_SETPIC and FBIOCONDECOR_SETSTATE commands,
2325 -+ in the above-mentioned order.
2326 -+
2327 -+ When the userspace helper is called in an early phase of the boot process
2328 -+ (right after the initialization of fbcon), no filesystems will be mounted.
2329 -+ The helper program should mount sysfs and then create the appropriate
2330 -+ framebuffer, fbcondecor and tty0 devices (if they don't already exist) to get
2331 -+ current display settings and to be able to communicate with the kernel side.
2332 -+ It should probably also mount the procfs to be able to parse the kernel
2333 -+ command line parameters.
2334 -+
2335 -+ Note that the console sem is not held when the kernel calls fbcondecor_helper
2336 -+ with the 'init' command. The fbcondecor helper should perform all ioctls with
2337 -+ origin set to FBCON_DECOR_IO_ORIG_USER.
2338 -+
2339 -+modechange
2340 -+----------
2341 -+ The kernel issues this command on a mode change. The helper's response should
2342 -+ be similar to the response to the 'init' command. Note that this time the
2343 -+ console sem is held and all ioctls must be performed with origin set to
2344 -+ FBCON_DECOR_IO_ORIG_KERNEL.
2345 -+
2346 -+
2347 -+Userspace -> Kernel
2348 -+-------------------
2349 -+
2350 -+Userspace programs can communicate with fbcondecor via ioctls on the
2351 -+fbcondecor device. These ioctls are to be used by both the userspace helper
2352 -+(called only by the kernel) and userspace configuration tools (run by the users).
2353 -+
2354 -+The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL
2355 -+when doing the appropriate ioctls. All userspace configuration tools should
2356 -+use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin
2357 -+field when performing ioctls from the kernel helper will most likely result
2358 -+in a console deadlock.
2359 -+
2360 -+FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console
2361 -+semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire
2362 -+the console sem.
2363 -+
2364 -+The framebuffer console decoration provides the following ioctls (all defined in
2365 -+linux/fb.h):
2366 -+
2367 -+FBIOCONDECOR_SETPIC
2368 -+description: loads a background picture for a virtual console
2369 -+argument: struct fbcon_decor_iowrapper*; data: struct fb_image*
2370 -+notes:
2371 -+If called for consoles other than the current foreground one, the picture data
2372 -+will be ignored.
2373 -+
2374 -+If the current virtual console is running in a 8-bpp mode, the cmap substruct
2375 -+of fb_image has to be filled appropriately: start should be set to 16 (first
2376 -+16 colors are reserved for fbcon), len to a value <= 240 and red, green and
2377 -+blue should point to valid cmap data. The transp field is ingored. The fields
2378 -+dx, dy, bg_color, fg_color in fb_image are ignored as well.
2379 -+
2380 -+FBIOCONDECOR_SETCFG
2381 -+description: sets the fbcondecor config for a virtual console
2382 -+argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
2383 -+notes: The structure has to be filled with valid data.
2384 -+
2385 -+FBIOCONDECOR_GETCFG
2386 -+description: gets the fbcondecor config for a virtual console
2387 -+argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
2388 -+
2389 -+FBIOCONDECOR_SETSTATE
2390 -+description: sets the fbcondecor state for a virtual console
2391 -+argument: struct fbcon_decor_iowrapper*; data: unsigned int*
2392 -+ values: 0 = disabled, 1 = enabled.
2393 -+
2394 -+FBIOCONDECOR_GETSTATE
2395 -+description: gets the fbcondecor state for a virtual console
2396 -+argument: struct fbcon_decor_iowrapper*; data: unsigned int*
2397 -+ values: as in FBIOCONDECOR_SETSTATE
2398 -+
2399 -+Info on used structures:
2400 -+
2401 -+Definition of struct vc_decor can be found in linux/console_decor.h. It's
2402 -+heavily commented. Note that the 'theme' field should point to a string
2403 -+no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is
2404 -+performed, the theme field should point to a char buffer of length
2405 -+FBCON_DECOR_THEME_LEN.
2406 -+
2407 -+Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h.
2408 -+The fields in this struct have the following meaning:
2409 -+
2410 -+vc:
2411 -+Virtual console number.
2412 -+
2413 -+origin:
2414 -+Specifies if the ioctl is performed as a response to a kernel request. The
2415 -+fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace
2416 -+programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to
2417 -+avoid console semaphore deadlocks.
2418 -+
2419 -+data:
2420 -+Pointer to a data structure appropriate for the performed ioctl. Type of
2421 -+the data struct is specified in the ioctls description.
2422 -+
2423 -+*****************************************************************************
2424 -+
2425 -+Credit
2426 -+------
2427 -+
2428 -+Original 'bootsplash' project & implementation by:
2429 -+ Volker Poplawski <volker@×××××××××.de>, Stefan Reinauer <stepan@××××.de>,
2430 -+ Steffen Winterfeldt <snwint@××××.de>, Michael Schroeder <mls@××××.de>,
2431 -+ Ken Wimer <wimer@××××.de>.
2432 -+
2433 -+Fbcondecor, fbcondecor protocol design, current implementation & docs by:
2434 -+ Michal Januszewski <spock@g.o>
2435 -+
2436 -diff --git a/drivers/Makefile b/drivers/Makefile
2437 -index bc4205d..794ce71 100644
2438 ---- a/drivers/Makefile
2439 -+++ b/drivers/Makefile
2440 -@@ -9,6 +9,9 @@ obj-y += gpio/
2441 - obj-$(CONFIG_PCI) += pci/
2442 - obj-$(CONFIG_PARISC) += parisc/
2443 - obj-$(CONFIG_RAPIDIO) += rapidio/
2444 -+# char/ comes before serial/ etc so that the VT console is the boot-time
2445 -+# default.
2446 -+obj-y += char/
2447 - obj-y += video/
2448 - obj-$(CONFIG_ACPI) += acpi/
2449 - # PnP must come after ACPI since it will eventually need to check if acpi
2450 -@@ -21,10 +24,6 @@ obj-$(CONFIG_XEN) += xen/
2451 - # regulators early, since some subsystems rely on them to initialize
2452 - obj-$(CONFIG_REGULATOR) += regulator/
2453 -
2454 --# char/ comes before serial/ etc so that the VT console is the boot-time
2455 --# default.
2456 --obj-y += char/
2457 --
2458 - # gpu/ comes after char for AGP vs DRM startup
2459 - obj-y += gpu/
2460 -
2461 -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
2462 -index 3b54b39..23ce357 100644
2463 ---- a/drivers/video/Kconfig
2464 -+++ b/drivers/video/Kconfig
2465 -@@ -1160,7 +1160,6 @@ config FB_MATROX
2466 - select FB_CFB_FILLRECT
2467 - select FB_CFB_COPYAREA
2468 - select FB_CFB_IMAGEBLIT
2469 -- select FB_TILEBLITTING
2470 - select FB_MACMODES if PPC_PMAC
2471 - ---help---
2472 - Say Y here if you have a Matrox Millennium, Matrox Millennium II,
2473 -diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
2474 -index 2f50a80..aa73fb7 100644
2475 ---- a/drivers/video/console/Kconfig
2476 -+++ b/drivers/video/console/Kconfig
2477 -@@ -128,6 +128,19 @@ config FRAMEBUFFER_CONSOLE_ROTATION
2478 - such that other users of the framebuffer will remain normally
2479 - oriented.
2480 -
2481 -+config FB_CON_DECOR
2482 -+ bool "Support for the Framebuffer Console Decorations"
2483 -+ depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
2484 -+ default n
2485 -+ ---help---
2486 -+ This option enables support for framebuffer console decorations which
2487 -+ makes it possible to display images in the background of the system
2488 -+ consoles. Note that userspace utilities are necessary in order to take
2489 -+ advantage of these features. Refer to Documentation/fb/fbcondecor.txt
2490 -+ for more information.
2491 -+
2492 -+ If unsure, say N.
2493 -+
2494 - config STI_CONSOLE
2495 - bool "STI text console"
2496 - depends on PARISC
2497 -diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
2498 -index ac46cc3..e300ea0 100644
2499 ---- a/drivers/video/console/Makefile
2500 -+++ b/drivers/video/console/Makefile
2501 -@@ -35,6 +35,7 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
2502 - fbcon_ccw.o
2503 - endif
2504 -
2505 -+obj-$(CONFIG_FB_CON_DECOR) += fbcondecor.o cfbcondecor.o
2506 - obj-$(CONFIG_FB_STI) += sticore.o font.o
2507 -
2508 - ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
2509 -diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
2510 -index 69864b1..77c1feb 100644
2511 ---- a/drivers/video/console/bitblit.c
2512 -+++ b/drivers/video/console/bitblit.c
2513 -@@ -17,6 +17,7 @@
2514 - #include <linux/console.h>
2515 - #include <asm/types.h>
2516 - #include "fbcon.h"
2517 -+#include "fbcondecor.h"
2518 -
2519 - /*
2520 - * Accelerated handlers.
2521 -@@ -54,6 +55,13 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
2522 - area.height = height * vc->vc_font.height;
2523 - area.width = width * vc->vc_font.width;
2524 -
2525 -+ if (fbcon_decor_active(info, vc)) {
2526 -+ area.sx += vc->vc_decor.tx;
2527 -+ area.sy += vc->vc_decor.ty;
2528 -+ area.dx += vc->vc_decor.tx;
2529 -+ area.dy += vc->vc_decor.ty;
2530 -+ }
2531 -+
2532 - info->fbops->fb_copyarea(info, &area);
2533 - }
2534 -
2535 -@@ -379,11 +387,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
2536 - cursor.image.depth = 1;
2537 - cursor.rop = ROP_XOR;
2538 -
2539 -- if (info->fbops->fb_cursor)
2540 -- err = info->fbops->fb_cursor(info, &cursor);
2541 -+ if (fbcon_decor_active(info, vc)) {
2542 -+ fbcon_decor_cursor(info, &cursor);
2543 -+ } else {
2544 -+ if (info->fbops->fb_cursor)
2545 -+ err = info->fbops->fb_cursor(info, &cursor);
2546 -
2547 -- if (err)
2548 -- soft_cursor(info, &cursor);
2549 -+ if (err)
2550 -+ soft_cursor(info, &cursor);
2551 -+ }
2552 -
2553 - ops->cursor_reset = 0;
2554 - }
2555 -diff --git a/drivers/video/console/cfbcondecor.c b/drivers/video/console/cfbcondecor.c
2556 -new file mode 100644
2557 -index 0000000..7654ec6
2558 ---- /dev/null
2559 -+++ b/drivers/video/console/cfbcondecor.c
2560 -@@ -0,0 +1,471 @@
2561 -+/*
2562 -+ * linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions
2563 -+ *
2564 -+ * Copyright (C) 2004 Michal Januszewski <spock@g.o>
2565 -+ *
2566 -+ * Code based upon "Bootdecor" (C) 2001-2003
2567 -+ * Volker Poplawski <volker@×××××××××.de>,
2568 -+ * Stefan Reinauer <stepan@××××.de>,
2569 -+ * Steffen Winterfeldt <snwint@××××.de>,
2570 -+ * Michael Schroeder <mls@××××.de>,
2571 -+ * Ken Wimer <wimer@××××.de>.
2572 -+ *
2573 -+ * This file is subject to the terms and conditions of the GNU General Public
2574 -+ * License. See the file COPYING in the main directory of this archive for
2575 -+ * more details.
2576 -+ */
2577 -+#include <linux/module.h>
2578 -+#include <linux/types.h>
2579 -+#include <linux/fb.h>
2580 -+#include <linux/selection.h>
2581 -+#include <linux/vt_kern.h>
2582 -+#include <asm/irq.h>
2583 -+#include <asm/system.h>
2584 -+
2585 -+#include "fbcon.h"
2586 -+#include "fbcondecor.h"
2587 -+
2588 -+#define parse_pixel(shift,bpp,type) \
2589 -+ do { \
2590 -+ if (d & (0x80 >> (shift))) \
2591 -+ dd2[(shift)] = fgx; \
2592 -+ else \
2593 -+ dd2[(shift)] = transparent ? *(type *)decor_src : bgx; \
2594 -+ decor_src += (bpp); \
2595 -+ } while (0) \
2596 -+
2597 -+extern int get_color(struct vc_data *vc, struct fb_info *info,
2598 -+ u16 c, int is_fg);
2599 -+
2600 -+void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc)
2601 -+{
2602 -+ int i, j, k;
2603 -+ int minlen = min(min(info->var.red.length, info->var.green.length),
2604 -+ info->var.blue.length);
2605 -+ u32 col;
2606 -+
2607 -+ for (j = i = 0; i < 16; i++) {
2608 -+ k = color_table[i];
2609 -+
2610 -+ col = ((vc->vc_palette[j++] >> (8-minlen))
2611 -+ << info->var.red.offset);
2612 -+ col |= ((vc->vc_palette[j++] >> (8-minlen))
2613 -+ << info->var.green.offset);
2614 -+ col |= ((vc->vc_palette[j++] >> (8-minlen))
2615 -+ << info->var.blue.offset);
2616 -+ ((u32 *)info->pseudo_palette)[k] = col;
2617 -+ }
2618 -+}
2619 -+
2620 -+void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height,
2621 -+ int width, u8* src, u32 fgx, u32 bgx, u8 transparent)
2622 -+{
2623 -+ unsigned int x, y;
2624 -+ u32 dd;
2625 -+ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
2626 -+ unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
2627 -+ unsigned int ds = (ypos * info->var.xres + xpos) * bytespp;
2628 -+ u16 dd2[4];
2629 -+
2630 -+ u8* decor_src = (u8 *)(info->bgdecor.data + ds);
2631 -+ u8* dst = (u8 *)(info->screen_base + d);
2632 -+
2633 -+ if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
2634 -+ return;
2635 -+
2636 -+ for (y = 0; y < height; y++) {
2637 -+ switch (info->var.bits_per_pixel) {
2638 -+
2639 -+ case 32:
2640 -+ for (x = 0; x < width; x++) {
2641 -+
2642 -+ if ((x & 7) == 0)
2643 -+ d = *src++;
2644 -+ if (d & 0x80)
2645 -+ dd = fgx;
2646 -+ else
2647 -+ dd = transparent ?
2648 -+ *(u32 *)decor_src : bgx;
2649 -+
2650 -+ d <<= 1;
2651 -+ decor_src += 4;
2652 -+ fb_writel(dd, dst);
2653 -+ dst += 4;
2654 -+ }
2655 -+ break;
2656 -+ case 24:
2657 -+ for (x = 0; x < width; x++) {
2658 -+
2659 -+ if ((x & 7) == 0)
2660 -+ d = *src++;
2661 -+ if (d & 0x80)
2662 -+ dd = fgx;
2663 -+ else
2664 -+ dd = transparent ?
2665 -+ (*(u32 *)decor_src & 0xffffff) : bgx;
2666 -+
2667 -+ d <<= 1;
2668 -+ decor_src += 3;
2669 -+#ifdef __LITTLE_ENDIAN
2670 -+ fb_writew(dd & 0xffff, dst);
2671 -+ dst += 2;
2672 -+ fb_writeb((dd >> 16), dst);
2673 -+#else
2674 -+ fb_writew(dd >> 8, dst);
2675 -+ dst += 2;
2676 -+ fb_writeb(dd & 0xff, dst);
2677 -+#endif
2678 -+ dst++;
2679 -+ }
2680 -+ break;
2681 -+ case 16:
2682 -+ for (x = 0; x < width; x += 2) {
2683 -+ if ((x & 7) == 0)
2684 -+ d = *src++;
2685 -+
2686 -+ parse_pixel(0, 2, u16);
2687 -+ parse_pixel(1, 2, u16);
2688 -+#ifdef __LITTLE_ENDIAN
2689 -+ dd = dd2[0] | (dd2[1] << 16);
2690 -+#else
2691 -+ dd = dd2[1] | (dd2[0] << 16);
2692 -+#endif
2693 -+ d <<= 2;
2694 -+ fb_writel(dd, dst);
2695 -+ dst += 4;
2696 -+ }
2697 -+ break;
2698 -+
2699 -+ case 8:
2700 -+ for (x = 0; x < width; x += 4) {
2701 -+ if ((x & 7) == 0)
2702 -+ d = *src++;
2703 -+
2704 -+ parse_pixel(0, 1, u8);
2705 -+ parse_pixel(1, 1, u8);
2706 -+ parse_pixel(2, 1, u8);
2707 -+ parse_pixel(3, 1, u8);
2708 -+
2709 -+#ifdef __LITTLE_ENDIAN
2710 -+ dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
2711 -+#else
2712 -+ dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
2713 -+#endif
2714 -+ d <<= 4;
2715 -+ fb_writel(dd, dst);
2716 -+ dst += 4;
2717 -+ }
2718 -+ }
2719 -+
2720 -+ dst += info->fix.line_length - width * bytespp;
2721 -+ decor_src += (info->var.xres - width) * bytespp;
2722 -+ }
2723 -+}
2724 -+
2725 -+#define cc2cx(a) \
2726 -+ ((info->fix.visual == FB_VISUAL_TRUECOLOR || \
2727 -+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \
2728 -+ ((u32*)info->pseudo_palette)[a] : a)
2729 -+
2730 -+void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info,
2731 -+ const unsigned short *s, int count, int yy, int xx)
2732 -+{
2733 -+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
2734 -+ struct fbcon_ops *ops = info->fbcon_par;
2735 -+ int fg_color, bg_color, transparent;
2736 -+ u8 *src;
2737 -+ u32 bgx, fgx;
2738 -+ u16 c = scr_readw(s);
2739 -+
2740 -+ fg_color = get_color(vc, info, c, 1);
2741 -+ bg_color = get_color(vc, info, c, 0);
2742 -+
2743 -+ /* Don't paint the background image if console is blanked */
2744 -+ transparent = ops->blank_state ? 0 :
2745 -+ (vc->vc_decor.bg_color == bg_color);
2746 -+
2747 -+ xx = xx * vc->vc_font.width + vc->vc_decor.tx;
2748 -+ yy = yy * vc->vc_font.height + vc->vc_decor.ty;
2749 -+
2750 -+ fgx = cc2cx(fg_color);
2751 -+ bgx = cc2cx(bg_color);
2752 -+
2753 -+ while (count--) {
2754 -+ c = scr_readw(s++);
2755 -+ src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
2756 -+ ((vc->vc_font.width + 7) >> 3);
2757 -+
2758 -+ fbcon_decor_renderc(info, yy, xx, vc->vc_font.height,
2759 -+ vc->vc_font.width, src, fgx, bgx, transparent);
2760 -+ xx += vc->vc_font.width;
2761 -+ }
2762 -+}
2763 -+
2764 -+void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor)
2765 -+{
2766 -+ int i;
2767 -+ unsigned int dsize, s_pitch;
2768 -+ struct fbcon_ops *ops = info->fbcon_par;
2769 -+ struct vc_data* vc;
2770 -+ u8 *src;
2771 -+
2772 -+ /* we really don't need any cursors while the console is blanked */
2773 -+ if (info->state != FBINFO_STATE_RUNNING || ops->blank_state)
2774 -+ return;
2775 -+
2776 -+ vc = vc_cons[ops->currcon].d;
2777 -+
2778 -+ src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC);
2779 -+ if (!src)
2780 -+ return;
2781 -+
2782 -+ s_pitch = (cursor->image.width + 7) >> 3;
2783 -+ dsize = s_pitch * cursor->image.height;
2784 -+ if (cursor->enable) {
2785 -+ switch (cursor->rop) {
2786 -+ case ROP_XOR:
2787 -+ for (i = 0; i < dsize; i++)
2788 -+ src[i] = cursor->image.data[i] ^ cursor->mask[i];
2789 -+ break;
2790 -+ case ROP_COPY:
2791 -+ default:
2792 -+ for (i = 0; i < dsize; i++)
2793 -+ src[i] = cursor->image.data[i] & cursor->mask[i];
2794 -+ break;
2795 -+ }
2796 -+ } else
2797 -+ memcpy(src, cursor->image.data, dsize);
2798 -+
2799 -+ fbcon_decor_renderc(info,
2800 -+ cursor->image.dy + vc->vc_decor.ty,
2801 -+ cursor->image.dx + vc->vc_decor.tx,
2802 -+ cursor->image.height,
2803 -+ cursor->image.width,
2804 -+ (u8*)src,
2805 -+ cc2cx(cursor->image.fg_color),
2806 -+ cc2cx(cursor->image.bg_color),
2807 -+ cursor->image.bg_color == vc->vc_decor.bg_color);
2808 -+
2809 -+ kfree(src);
2810 -+}
2811 -+
2812 -+static void decorset(u8 *dst, int height, int width, int dstbytes,
2813 -+ u32 bgx, int bpp)
2814 -+{
2815 -+ int i;
2816 -+
2817 -+ if (bpp == 8)
2818 -+ bgx |= bgx << 8;
2819 -+ if (bpp == 16 || bpp == 8)
2820 -+ bgx |= bgx << 16;
2821 -+
2822 -+ while (height-- > 0) {
2823 -+ u8 *p = dst;
2824 -+
2825 -+ switch (bpp) {
2826 -+
2827 -+ case 32:
2828 -+ for (i=0; i < width; i++) {
2829 -+ fb_writel(bgx, p); p += 4;
2830 -+ }
2831 -+ break;
2832 -+ case 24:
2833 -+ for (i=0; i < width; i++) {
2834 -+#ifdef __LITTLE_ENDIAN
2835 -+ fb_writew((bgx & 0xffff),(u16*)p); p += 2;
2836 -+ fb_writeb((bgx >> 16),p++);
2837 -+#else
2838 -+ fb_writew((bgx >> 8),(u16*)p); p += 2;
2839 -+ fb_writeb((bgx & 0xff),p++);
2840 -+#endif
2841 -+ }
2842 -+ case 16:
2843 -+ for (i=0; i < width/4; i++) {
2844 -+ fb_writel(bgx,p); p += 4;
2845 -+ fb_writel(bgx,p); p += 4;
2846 -+ }
2847 -+ if (width & 2) {
2848 -+ fb_writel(bgx,p); p += 4;
2849 -+ }
2850 -+ if (width & 1)
2851 -+ fb_writew(bgx,(u16*)p);
2852 -+ break;
2853 -+ case 8:
2854 -+ for (i=0; i < width/4; i++) {
2855 -+ fb_writel(bgx,p); p += 4;
2856 -+ }
2857 -+
2858 -+ if (width & 2) {
2859 -+ fb_writew(bgx,p); p += 2;
2860 -+ }
2861 -+ if (width & 1)
2862 -+ fb_writeb(bgx,(u8*)p);
2863 -+ break;
2864 -+
2865 -+ }
2866 -+ dst += dstbytes;
2867 -+ }
2868 -+}
2869 -+
2870 -+void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
2871 -+ int srclinebytes, int bpp)
2872 -+{
2873 -+ int i;
2874 -+
2875 -+ while (height-- > 0) {
2876 -+ u32 *p = (u32 *)dst;
2877 -+ u32 *q = (u32 *)src;
2878 -+
2879 -+ switch (bpp) {
2880 -+
2881 -+ case 32:
2882 -+ for (i=0; i < width; i++)
2883 -+ fb_writel(*q++, p++);
2884 -+ break;
2885 -+ case 24:
2886 -+ for (i=0; i < (width*3/4); i++)
2887 -+ fb_writel(*q++, p++);
2888 -+ if ((width*3) % 4) {
2889 -+ if (width & 2) {
2890 -+ fb_writeb(*(u8*)q, (u8*)p);
2891 -+ } else if (width & 1) {
2892 -+ fb_writew(*(u16*)q, (u16*)p);
2893 -+ fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2));
2894 -+ }
2895 -+ }
2896 -+ break;
2897 -+ case 16:
2898 -+ for (i=0; i < width/4; i++) {
2899 -+ fb_writel(*q++, p++);
2900 -+ fb_writel(*q++, p++);
2901 -+ }
2902 -+ if (width & 2)
2903 -+ fb_writel(*q++, p++);
2904 -+ if (width & 1)
2905 -+ fb_writew(*(u16*)q, (u16*)p);
2906 -+ break;
2907 -+ case 8:
2908 -+ for (i=0; i < width/4; i++)
2909 -+ fb_writel(*q++, p++);
2910 -+
2911 -+ if (width & 2) {
2912 -+ fb_writew(*(u16*)q, (u16*)p);
2913 -+ q = (u32*) ((u16*)q + 1);
2914 -+ p = (u32*) ((u16*)p + 1);
2915 -+ }
2916 -+ if (width & 1)
2917 -+ fb_writeb(*(u8*)q, (u8*)p);
2918 -+ break;
2919 -+ }
2920 -+
2921 -+ dst += linebytes;
2922 -+ src += srclinebytes;
2923 -+ }
2924 -+}
2925 -+
2926 -+static void decorfill(struct fb_info *info, int sy, int sx, int height,
2927 -+ int width)
2928 -+{
2929 -+ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
2930 -+ int d = sy * info->fix.line_length + sx * bytespp;
2931 -+ int ds = (sy * info->var.xres + sx) * bytespp;
2932 -+
2933 -+ fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds),
2934 -+ height, width, info->fix.line_length, info->var.xres * bytespp,
2935 -+ info->var.bits_per_pixel);
2936 -+}
2937 -+
2938 -+void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
2939 -+ int height, int width)
2940 -+{
2941 -+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
2942 -+ struct fbcon_ops *ops = info->fbcon_par;
2943 -+ u8 *dst;
2944 -+ int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info);
2945 -+
2946 -+ transparent = (vc->vc_decor.bg_color == bg_color);
2947 -+ sy = sy * vc->vc_font.height + vc->vc_decor.ty;
2948 -+ sx = sx * vc->vc_font.width + vc->vc_decor.tx;
2949 -+ height *= vc->vc_font.height;
2950 -+ width *= vc->vc_font.width;
2951 -+
2952 -+ /* Don't paint the background image if console is blanked */
2953 -+ if (transparent && !ops->blank_state) {
2954 -+ decorfill(info, sy, sx, height, width);
2955 -+ } else {
2956 -+ dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
2957 -+ sx * ((info->var.bits_per_pixel + 7) >> 3));
2958 -+ decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
2959 -+ info->var.bits_per_pixel);
2960 -+ }
2961 -+}
2962 -+
2963 -+void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info,
2964 -+ int bottom_only)
2965 -+{
2966 -+ unsigned int tw = vc->vc_cols*vc->vc_font.width;
2967 -+ unsigned int th = vc->vc_rows*vc->vc_font.height;
2968 -+
2969 -+ if (!bottom_only) {
2970 -+ /* top margin */
2971 -+ decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres);
2972 -+ /* left margin */
2973 -+ decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx);
2974 -+ /* right margin */
2975 -+ decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th,
2976 -+ info->var.xres - vc->vc_decor.tx - tw);
2977 -+ }
2978 -+ decorfill(info, vc->vc_decor.ty + th, 0,
2979 -+ info->var.yres - vc->vc_decor.ty - th, info->var.xres);
2980 -+}
2981 -+
2982 -+void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y,
2983 -+ int sx, int dx, int width)
2984 -+{
2985 -+ u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
2986 -+ u16 *s = d + (dx - sx);
2987 -+ u16 *start = d;
2988 -+ u16 *ls = d;
2989 -+ u16 *le = d + width;
2990 -+ u16 c;
2991 -+ int x = dx;
2992 -+ u16 attr = 1;
2993 -+
2994 -+ do {
2995 -+ c = scr_readw(d);
2996 -+ if (attr != (c & 0xff00)) {
2997 -+ attr = c & 0xff00;
2998 -+ if (d > start) {
2999 -+ fbcon_decor_putcs(vc, info, start, d - start, y, x);
3000 -+ x += d - start;
3001 -+ start = d;
3002 -+ }
3003 -+ }
3004 -+ if (s >= ls && s < le && c == scr_readw(s)) {
3005 -+ if (d > start) {
3006 -+ fbcon_decor_putcs(vc, info, start, d - start, y, x);
3007 -+ x += d - start + 1;
3008 -+ start = d + 1;
3009 -+ } else {
3010 -+ x++;
3011 -+ start++;
3012 -+ }
3013 -+ }
3014 -+ s++;
3015 -+ d++;
3016 -+ } while (d < le);
3017 -+ if (d > start)
3018 -+ fbcon_decor_putcs(vc, info, start, d - start, y, x);
3019 -+}
3020 -+
3021 -+void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank)
3022 -+{
3023 -+ if (blank) {
3024 -+ decorset((u8 *)info->screen_base, info->var.yres, info->var.xres,
3025 -+ info->fix.line_length, 0, info->var.bits_per_pixel);
3026 -+ } else {
3027 -+ update_screen(vc);
3028 -+ fbcon_decor_clear_margins(vc, info, 0);
3029 -+ }
3030 -+}
3031 -+
3032 -diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
3033 -index 3a44695..6ba9550 100644
3034 ---- a/drivers/video/console/fbcon.c
3035 -+++ b/drivers/video/console/fbcon.c
3036 -@@ -80,6 +80,7 @@
3037 - #include <asm/system.h>
3038 -
3039 - #include "fbcon.h"
3040 -+#include "fbcondecor.h"
3041 -
3042 - #ifdef FBCONDEBUG
3043 - # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
3044 -@@ -95,7 +96,7 @@ enum {
3045 -
3046 - static struct display fb_display[MAX_NR_CONSOLES];
3047 -
3048 --static signed char con2fb_map[MAX_NR_CONSOLES];
3049 -+signed char con2fb_map[MAX_NR_CONSOLES];
3050 - static signed char con2fb_map_boot[MAX_NR_CONSOLES];
3051 -
3052 - static int logo_lines;
3053 -@@ -285,7 +286,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
3054 - vc->vc_mode != KD_TEXT || ops->graphics);
3055 - }
3056 -
3057 --static inline int get_color(struct vc_data *vc, struct fb_info *info,
3058 -+inline int get_color(struct vc_data *vc, struct fb_info *info,
3059 - u16 c, int is_fg)
3060 - {
3061 - int depth = fb_get_color_depth(&info->var, &info->fix);
3062 -@@ -390,6 +391,7 @@ static void fb_flashcursor(struct work_struct *work)
3063 - CM_ERASE : CM_DRAW;
3064 - ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
3065 - get_color(vc, info, c, 0));
3066 -+
3067 - release_console_sem();
3068 - }
3069 -
3070 -@@ -526,6 +528,7 @@ static int search_for_mapped_con(void)
3071 - static int fbcon_takeover(int show_logo)
3072 - {
3073 - int err, i;
3074 -+ struct fb_info *info;
3075 -
3076 - if (!num_registered_fb)
3077 - return -ENODEV;
3078 -@@ -542,11 +545,17 @@ static int fbcon_takeover(int show_logo)
3079 - err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,
3080 - fbcon_is_default);
3081 -
3082 -+ info = registered_fb[info_idx];
3083 -+
3084 - if (err) {
3085 - for (i = first_fb_vc; i <= last_fb_vc; i++) {
3086 - con2fb_map[i] = -1;
3087 - }
3088 - info_idx = -1;
3089 -+ } else {
3090 -+ unlock_fb_info(info);
3091 -+ fbcon_decor_init();
3092 -+ lock_fb_info(info);
3093 - }
3094 -
3095 - return err;
3096 -@@ -985,6 +994,12 @@ static const char *fbcon_startup(void)
3097 - rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3098 - cols /= vc->vc_font.width;
3099 - rows /= vc->vc_font.height;
3100 -+
3101 -+ if (fbcon_decor_active(info, vc)) {
3102 -+ cols = vc->vc_decor.twidth / vc->vc_font.width;
3103 -+ rows = vc->vc_decor.theight / vc->vc_font.height;
3104 -+ }
3105 -+
3106 - vc_resize(vc, cols, rows);
3107 -
3108 - DPRINTK("mode: %s\n", info->fix.id);
3109 -@@ -1014,7 +1029,7 @@ static void fbcon_init(struct vc_data *vc, int init)
3110 - cap = info->flags;
3111 -
3112 - if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
3113 -- (info->fix.type == FB_TYPE_TEXT))
3114 -+ (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
3115 - logo = 0;
3116 -
3117 - if (var_to_display(p, &info->var, info))
3118 -@@ -1216,6 +1231,11 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
3119 - if (sy < vc->vc_top && vc->vc_top == logo_lines)
3120 - vc->vc_top = 0;
3121 -
3122 -+ if (fbcon_decor_active(info, vc)) {
3123 -+ fbcon_decor_clear(vc, info, sy, sx, height, width);
3124 -+ return;
3125 -+ }
3126 -+
3127 - /* Split blits that cross physical y_wrap boundary */
3128 -
3129 - y_break = p->vrows - p->yscroll;
3130 -@@ -1235,10 +1255,15 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
3131 - struct display *p = &fb_display[vc->vc_num];
3132 - struct fbcon_ops *ops = info->fbcon_par;
3133 -
3134 -- if (!fbcon_is_inactive(vc, info))
3135 -- ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
3136 -- get_color(vc, info, scr_readw(s), 1),
3137 -- get_color(vc, info, scr_readw(s), 0));
3138 -+ if (!fbcon_is_inactive(vc, info)) {
3139 -+
3140 -+ if (fbcon_decor_active(info, vc))
3141 -+ fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
3142 -+ else
3143 -+ ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
3144 -+ get_color(vc, info, scr_readw(s), 1),
3145 -+ get_color(vc, info, scr_readw(s), 0));
3146 -+ }
3147 - }
3148 -
3149 - static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
3150 -@@ -1254,8 +1279,13 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
3151 - struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
3152 - struct fbcon_ops *ops = info->fbcon_par;
3153 -
3154 -- if (!fbcon_is_inactive(vc, info))
3155 -- ops->clear_margins(vc, info, bottom_only);
3156 -+ if (!fbcon_is_inactive(vc, info)) {
3157 -+ if (fbcon_decor_active(info, vc)) {
3158 -+ fbcon_decor_clear_margins(vc, info, bottom_only);
3159 -+ } else {
3160 -+ ops->clear_margins(vc, info, bottom_only);
3161 -+ }
3162 -+ }
3163 - }
3164 -
3165 - static void fbcon_cursor(struct vc_data *vc, int mode)
3166 -@@ -1775,7 +1805,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
3167 - count = vc->vc_rows;
3168 - if (softback_top)
3169 - fbcon_softback_note(vc, t, count);
3170 -- if (logo_shown >= 0)
3171 -+ if (logo_shown >= 0 || fbcon_decor_active(info, vc))
3172 - goto redraw_up;
3173 - switch (p->scrollmode) {
3174 - case SCROLL_MOVE:
3175 -@@ -1868,6 +1898,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
3176 - count = vc->vc_rows;
3177 - if (logo_shown >= 0)
3178 - goto redraw_down;
3179 -+ if (fbcon_decor_active(info, vc))
3180 -+ goto redraw_down;
3181 - switch (p->scrollmode) {
3182 - case SCROLL_MOVE:
3183 - fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
3184 -@@ -2016,6 +2048,13 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
3185 - }
3186 - return;
3187 - }
3188 -+
3189 -+ if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
3190 -+ /* must use slower redraw bmove to keep background pic intact */
3191 -+ fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
3192 -+ return;
3193 -+ }
3194 -+
3195 - ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
3196 - height, width);
3197 - }
3198 -@@ -2086,8 +2125,8 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
3199 - var.yres = virt_h * virt_fh;
3200 - x_diff = info->var.xres - var.xres;
3201 - y_diff = info->var.yres - var.yres;
3202 -- if (x_diff < 0 || x_diff > virt_fw ||
3203 -- y_diff < 0 || y_diff > virt_fh) {
3204 -+ if ((x_diff < 0 || x_diff > virt_fw ||
3205 -+ y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
3206 - const struct fb_videomode *mode;
3207 -
3208 - DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
3209 -@@ -2123,6 +2162,19 @@ static int fbcon_switch(struct vc_data *vc)
3210 -
3211 - info = registered_fb[con2fb_map[vc->vc_num]];
3212 - ops = info->fbcon_par;
3213 -+ prev_console = ops->currcon;
3214 -+ if (prev_console != -1)
3215 -+ old_info = registered_fb[con2fb_map[prev_console]];
3216 -+
3217 -+ if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
3218 -+ struct vc_data *vc_curr = vc_cons[prev_console].d;
3219 -+ if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
3220 -+ /* Clear the screen to avoid displaying funky colors during
3221 -+ * palette updates. */
3222 -+ memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset,
3223 -+ 0, info->var.yres * info->fix.line_length);
3224 -+ }
3225 -+ }
3226 -
3227 - if (softback_top) {
3228 - if (softback_lines)
3229 -@@ -2141,9 +2193,6 @@ static int fbcon_switch(struct vc_data *vc)
3230 - logo_shown = FBCON_LOGO_CANSHOW;
3231 - }
3232 -
3233 -- prev_console = ops->currcon;
3234 -- if (prev_console != -1)
3235 -- old_info = registered_fb[con2fb_map[prev_console]];
3236 - /*
3237 - * FIXME: If we have multiple fbdev's loaded, we need to
3238 - * update all info->currcon. Perhaps, we can place this
3239 -@@ -2181,6 +2230,18 @@ static int fbcon_switch(struct vc_data *vc)
3240 - fbcon_del_cursor_timer(old_info);
3241 - }
3242 -
3243 -+ if (fbcon_decor_active_vc(vc)) {
3244 -+ struct vc_data *vc_curr = vc_cons[prev_console].d;
3245 -+
3246 -+ if (!vc_curr->vc_decor.theme ||
3247 -+ strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
3248 -+ (fbcon_decor_active_nores(info, vc_curr) &&
3249 -+ !fbcon_decor_active(info, vc_curr))) {
3250 -+ if (fbcon_decor_call_helper("modechange", vc->vc_num))
3251 -+ fbcon_decor_disable(vc, 0);
3252 -+ }
3253 -+ }
3254 -+
3255 - if (fbcon_is_inactive(vc, info) ||
3256 - ops->blank_state != FB_BLANK_UNBLANK)
3257 - fbcon_del_cursor_timer(info);
3258 -@@ -2292,15 +2353,20 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
3259 - info->fbops->fb_restore_state(info);
3260 - }
3261 -
3262 -- if (!fbcon_is_inactive(vc, info)) {
3263 -+ if (!fbcon_is_inactive(vc, info)) {
3264 - if (ops->blank_state != blank) {
3265 - ops->blank_state = blank;
3266 - fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
3267 - ops->cursor_flash = (!blank);
3268 -
3269 -- if (!(info->flags & FBINFO_MISC_USEREVENT))
3270 -- if (fb_blank(info, blank))
3271 -- fbcon_generic_blank(vc, info, blank);
3272 -+ if (!(info->flags & FBINFO_MISC_USEREVENT)) {
3273 -+ if (fb_blank(info, blank)) {
3274 -+ if (fbcon_decor_active(info, vc))
3275 -+ fbcon_decor_blank(vc, info, blank);
3276 -+ else
3277 -+ fbcon_generic_blank(vc, info, blank);
3278 -+ }
3279 -+ }
3280 - }
3281 -
3282 - if (!blank)
3283 -@@ -2451,13 +2517,22 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
3284 - }
3285 -
3286 - if (resize) {
3287 -+ /* reset wrap/pan */
3288 - int cols, rows;
3289 -
3290 - cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
3291 - rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3292 -+
3293 -+ info->var.xoffset = info->var.yoffset = p->yscroll = 0;
3294 -+ if (fbcon_decor_active(info, vc)) {
3295 -+ cols = vc->vc_decor.twidth;
3296 -+ rows = vc->vc_decor.theight;
3297 -+ }
3298 - cols /= w;
3299 - rows /= h;
3300 -+
3301 - vc_resize(vc, cols, rows);
3302 -+
3303 - if (CON_IS_VISIBLE(vc) && softback_buf)
3304 - fbcon_update_softback(vc);
3305 - } else if (CON_IS_VISIBLE(vc)
3306 -@@ -2586,7 +2661,7 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
3307 - int i, j, k, depth;
3308 - u8 val;
3309 -
3310 -- if (fbcon_is_inactive(vc, info))
3311 -+ if (fbcon_is_inactive(vc, info) || vc->vc_num != fg_console)
3312 - return -EINVAL;
3313 -
3314 - if (!CON_IS_VISIBLE(vc))
3315 -@@ -2612,7 +2687,49 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
3316 - } else
3317 - fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
3318 -
3319 -- return fb_set_cmap(&palette_cmap, info);
3320 -+ if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
3321 -+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
3322 -+
3323 -+ u16 *red, *green, *blue;
3324 -+ int minlen = min(min(info->var.red.length, info->var.green.length),
3325 -+ info->var.blue.length);
3326 -+ int h;
3327 -+
3328 -+ struct fb_cmap cmap = {
3329 -+ .start = 0,
3330 -+ .len = (1 << minlen),
3331 -+ .red = NULL,
3332 -+ .green = NULL,
3333 -+ .blue = NULL,
3334 -+ .transp = NULL
3335 -+ };
3336 -+
3337 -+ red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
3338 -+
3339 -+ if (!red)
3340 -+ goto out;
3341 -+
3342 -+ green = red + 256;
3343 -+ blue = green + 256;
3344 -+ cmap.red = red;
3345 -+ cmap.green = green;
3346 -+ cmap.blue = blue;
3347 -+
3348 -+ for (i = 0; i < cmap.len; i++) {
3349 -+ red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
3350 -+ }
3351 -+
3352 -+ h = fb_set_cmap(&cmap, info);
3353 -+ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
3354 -+ kfree(red);
3355 -+
3356 -+ return h;
3357 -+
3358 -+ } else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
3359 -+ info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
3360 -+ fb_set_cmap(&info->bgdecor.cmap, info);
3361 -+
3362 -+out: return fb_set_cmap(&palette_cmap, info);
3363 - }
3364 -
3365 - static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
3366 -@@ -2838,7 +2955,18 @@ static void fbcon_modechanged(struct fb_info *info)
3367 - rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3368 - cols /= vc->vc_font.width;
3369 - rows /= vc->vc_font.height;
3370 -- vc_resize(vc, cols, rows);
3371 -+
3372 -+ if (!fbcon_decor_active_nores(info, vc)) {
3373 -+ vc_resize(vc, cols, rows);
3374 -+ } else {
3375 -+ /* HACK: Do this properly at some point.. */
3376 -+ unlock_fb_info(info);
3377 -+ int res = fbcon_decor_call_helper("modechange", vc->vc_num);
3378 -+ lock_fb_info(info);
3379 -+ if (res)
3380 -+ fbcon_decor_disable(vc, 0);
3381 -+ }
3382 -+
3383 - updatescrollmode(p, info, vc);
3384 - scrollback_max = 0;
3385 - scrollback_current = 0;
3386 -@@ -3465,6 +3593,7 @@ static void fbcon_exit(void)
3387 - }
3388 - }
3389 -
3390 -+ fbcon_decor_exit();
3391 - fbcon_has_exited = 1;
3392 - }
3393 -
3394 -diff --git a/drivers/video/console/fbcondecor.c b/drivers/video/console/fbcondecor.c
3395 -new file mode 100644
3396 -index 0000000..a0b4ae3
3397 ---- /dev/null
3398 -+++ b/drivers/video/console/fbcondecor.c
3399 -@@ -0,0 +1,561 @@
3400 -+/*
3401 -+ * linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations
3402 -+ *
3403 -+ * Copyright (C) 2004-2009 Michal Januszewski <spock@g.o>
3404 -+ *
3405 -+ * Code based upon "Bootsplash" (C) 2001-2003
3406 -+ * Volker Poplawski <volker@×××××××××.de>,
3407 -+ * Stefan Reinauer <stepan@××××.de>,
3408 -+ * Steffen Winterfeldt <snwint@××××.de>,
3409 -+ * Michael Schroeder <mls@××××.de>,
3410 -+ * Ken Wimer <wimer@××××.de>.
3411 -+ *
3412 -+ * Compat ioctl support by Thorsten Klein <TK@××××××××××××××.de>.
3413 -+ *
3414 -+ * This file is subject to the terms and conditions of the GNU General Public
3415 -+ * License. See the file COPYING in the main directory of this archive for
3416 -+ * more details.
3417 -+ *
3418 -+ */
3419 -+#include <linux/module.h>
3420 -+#include <linux/kernel.h>
3421 -+#include <linux/string.h>
3422 -+#include <linux/types.h>
3423 -+#include <linux/fb.h>
3424 -+#include <linux/vt_kern.h>
3425 -+#include <linux/vmalloc.h>
3426 -+#include <linux/unistd.h>
3427 -+#include <linux/syscalls.h>
3428 -+#include <linux/init.h>
3429 -+#include <linux/proc_fs.h>
3430 -+#include <linux/workqueue.h>
3431 -+#include <linux/kmod.h>
3432 -+#include <linux/miscdevice.h>
3433 -+#include <linux/device.h>
3434 -+#include <linux/fs.h>
3435 -+#include <linux/compat.h>
3436 -+
3437 -+#include <asm/uaccess.h>
3438 -+#include <asm/irq.h>
3439 -+#include <asm/system.h>
3440 -+
3441 -+#include "fbcon.h"
3442 -+#include "fbcondecor.h"
3443 -+
3444 -+extern signed char con2fb_map[];
3445 -+static int fbcon_decor_enable(struct vc_data *vc);
3446 -+char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
3447 -+static int initialized = 0;
3448 -+
3449 -+int fbcon_decor_call_helper(char* cmd, unsigned short vc)
3450 -+{
3451 -+ char *envp[] = {
3452 -+ "HOME=/",
3453 -+ "PATH=/sbin:/bin",
3454 -+ NULL
3455 -+ };
3456 -+
3457 -+ char tfb[5];
3458 -+ char tcons[5];
3459 -+ unsigned char fb = (int) con2fb_map[vc];
3460 -+
3461 -+ char *argv[] = {
3462 -+ fbcon_decor_path,
3463 -+ "2",
3464 -+ cmd,
3465 -+ tcons,
3466 -+ tfb,
3467 -+ vc_cons[vc].d->vc_decor.theme,
3468 -+ NULL
3469 -+ };
3470 -+
3471 -+ snprintf(tfb,5,"%d",fb);
3472 -+ snprintf(tcons,5,"%d",vc);
3473 -+
3474 -+ return call_usermodehelper(fbcon_decor_path, argv, envp, 1);
3475 -+}
3476 -+
3477 -+/* Disables fbcondecor on a virtual console; called with console sem held. */
3478 -+int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw)
3479 -+{
3480 -+ struct fb_info* info;
3481 -+
3482 -+ if (!vc->vc_decor.state)
3483 -+ return -EINVAL;
3484 -+
3485 -+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
3486 -+
3487 -+ if (info == NULL)
3488 -+ return -EINVAL;
3489 -+
3490 -+ vc->vc_decor.state = 0;
3491 -+ vc_resize(vc, info->var.xres / vc->vc_font.width,
3492 -+ info->var.yres / vc->vc_font.height);
3493 -+
3494 -+ if (fg_console == vc->vc_num && redraw) {
3495 -+ redraw_screen(vc, 0);
3496 -+ update_region(vc, vc->vc_origin +
3497 -+ vc->vc_size_row * vc->vc_top,
3498 -+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
3499 -+ }
3500 -+
3501 -+ printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n",
3502 -+ vc->vc_num);
3503 -+
3504 -+ return 0;
3505 -+}
3506 -+
3507 -+/* Enables fbcondecor on a virtual console; called with console sem held. */
3508 -+static int fbcon_decor_enable(struct vc_data *vc)
3509 -+{
3510 -+ struct fb_info* info;
3511 -+
3512 -+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
3513 -+
3514 -+ if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 ||
3515 -+ info == NULL || vc->vc_decor.state || (!info->bgdecor.data &&
3516 -+ vc->vc_num == fg_console))
3517 -+ return -EINVAL;
3518 -+
3519 -+ vc->vc_decor.state = 1;
3520 -+ vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width,
3521 -+ vc->vc_decor.theight / vc->vc_font.height);
3522 -+
3523 -+ if (fg_console == vc->vc_num) {
3524 -+ redraw_screen(vc, 0);
3525 -+ update_region(vc, vc->vc_origin +
3526 -+ vc->vc_size_row * vc->vc_top,
3527 -+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
3528 -+ fbcon_decor_clear_margins(vc, info, 0);
3529 -+ }
3530 -+
3531 -+ printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n",
3532 -+ vc->vc_num);
3533 -+
3534 -+ return 0;
3535 -+}
3536 -+
3537 -+static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin)
3538 -+{
3539 -+ int ret;
3540 -+
3541 -+ if (origin == FBCON_DECOR_IO_ORIG_USER)
3542 -+ acquire_console_sem();
3543 -+ if (!state)
3544 -+ ret = fbcon_decor_disable(vc, 1);
3545 -+ else
3546 -+ ret = fbcon_decor_enable(vc);
3547 -+ if (origin == FBCON_DECOR_IO_ORIG_USER)
3548 -+ release_console_sem();
3549 -+
3550 -+ return ret;
3551 -+}
3552 -+
3553 -+static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state)
3554 -+{
3555 -+ *state = vc->vc_decor.state;
3556 -+}
3557 -+
3558 -+static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin)
3559 -+{
3560 -+ struct fb_info *info;
3561 -+ int len;
3562 -+ char *tmp;
3563 -+
3564 -+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
3565 -+
3566 -+ if (info == NULL || !cfg->twidth || !cfg->theight ||
3567 -+ cfg->tx + cfg->twidth > info->var.xres ||
3568 -+ cfg->ty + cfg->theight > info->var.yres)
3569 -+ return -EINVAL;
3570 -+
3571 -+ len = strlen_user(cfg->theme);
3572 -+ if (!len || len > FBCON_DECOR_THEME_LEN)
3573 -+ return -EINVAL;
3574 -+ tmp = kmalloc(len, GFP_KERNEL);
3575 -+ if (!tmp)
3576 -+ return -ENOMEM;
3577 -+ if (copy_from_user(tmp, (void __user *)cfg->theme, len))
3578 -+ return -EFAULT;
3579 -+ cfg->theme = tmp;
3580 -+ cfg->state = 0;
3581 -+
3582 -+ /* If this ioctl is a response to a request from kernel, the console sem
3583 -+ * is already held; we also don't need to disable decor because either the
3584 -+ * new config and background picture will be successfully loaded, and the
3585 -+ * decor will stay on, or in case of a failure it'll be turned off in fbcon. */
3586 -+ if (origin == FBCON_DECOR_IO_ORIG_USER) {
3587 -+ acquire_console_sem();
3588 -+ if (vc->vc_decor.state)
3589 -+ fbcon_decor_disable(vc, 1);
3590 -+ }
3591 -+
3592 -+ if (vc->vc_decor.theme)
3593 -+ kfree(vc->vc_decor.theme);
3594 -+
3595 -+ vc->vc_decor = *cfg;
3596 -+
3597 -+ if (origin == FBCON_DECOR_IO_ORIG_USER)
3598 -+ release_console_sem();
3599 -+
3600 -+ printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n",
3601 -+ vc->vc_num, vc->vc_decor.theme);
3602 -+ return 0;
3603 -+}
3604 -+
3605 -+static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc, struct vc_decor *decor)
3606 -+{
3607 -+ char __user *tmp;
3608 -+
3609 -+ tmp = decor->theme;
3610 -+ *decor = vc->vc_decor;
3611 -+ decor->theme = tmp;
3612 -+
3613 -+ if (vc->vc_decor.theme) {
3614 -+ if (copy_to_user(tmp, vc->vc_decor.theme, strlen(vc->vc_decor.theme) + 1))
3615 -+ return -EFAULT;
3616 -+ } else
3617 -+ if (put_user(0, tmp))
3618 -+ return -EFAULT;
3619 -+
3620 -+ return 0;
3621 -+}
3622 -+
3623 -+static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img, unsigned char origin)
3624 -+{
3625 -+ struct fb_info *info;
3626 -+ int len;
3627 -+ u8 *tmp;
3628 -+
3629 -+ if (vc->vc_num != fg_console)
3630 -+ return -EINVAL;
3631 -+
3632 -+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
3633 -+
3634 -+ if (info == NULL)
3635 -+ return -EINVAL;
3636 -+
3637 -+ if (img->width != info->var.xres || img->height != info->var.yres) {
3638 -+ printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n");
3639 -+ printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height, info->var.xres, info->var.yres);
3640 -+ return -EINVAL;
3641 -+ }
3642 -+
3643 -+ if (img->depth != info->var.bits_per_pixel) {
3644 -+ printk(KERN_ERR "fbcondecor: picture depth mismatch\n");
3645 -+ return -EINVAL;
3646 -+ }
3647 -+
3648 -+ if (img->depth == 8) {
3649 -+ if (!img->cmap.len || !img->cmap.red || !img->cmap.green ||
3650 -+ !img->cmap.blue)
3651 -+ return -EINVAL;
3652 -+
3653 -+ tmp = vmalloc(img->cmap.len * 3 * 2);
3654 -+ if (!tmp)
3655 -+ return -ENOMEM;
3656 -+
3657 -+ if (copy_from_user(tmp,
3658 -+ (void __user*)img->cmap.red, (img->cmap.len << 1)) ||
3659 -+ copy_from_user(tmp + (img->cmap.len << 1),
3660 -+ (void __user*)img->cmap.green, (img->cmap.len << 1)) ||
3661 -+ copy_from_user(tmp + (img->cmap.len << 2),
3662 -+ (void __user*)img->cmap.blue, (img->cmap.len << 1))) {
3663 -+ vfree(tmp);
3664 -+ return -EFAULT;
3665 -+ }
3666 -+
3667 -+ img->cmap.transp = NULL;
3668 -+ img->cmap.red = (u16*)tmp;
3669 -+ img->cmap.green = img->cmap.red + img->cmap.len;
3670 -+ img->cmap.blue = img->cmap.green + img->cmap.len;
3671 -+ } else {
3672 -+ img->cmap.red = NULL;
3673 -+ }
3674 -+
3675 -+ len = ((img->depth + 7) >> 3) * img->width * img->height;
3676 -+
3677 -+ /*
3678 -+ * Allocate an additional byte so that we never go outside of the
3679 -+ * buffer boundaries in the rendering functions in a 24 bpp mode.
3680 -+ */
3681 -+ tmp = vmalloc(len + 1);
3682 -+
3683 -+ if (!tmp)
3684 -+ goto out;
3685 -+
3686 -+ if (copy_from_user(tmp, (void __user*)img->data, len))
3687 -+ goto out;
3688 -+
3689 -+ img->data = tmp;
3690 -+
3691 -+ /* If this ioctl is a response to a request from kernel, the console sem
3692 -+ * is already held. */
3693 -+ if (origin == FBCON_DECOR_IO_ORIG_USER)
3694 -+ acquire_console_sem();
3695 -+
3696 -+ if (info->bgdecor.data)
3697 -+ vfree((u8*)info->bgdecor.data);
3698 -+ if (info->bgdecor.cmap.red)
3699 -+ vfree(info->bgdecor.cmap.red);
3700 -+
3701 -+ info->bgdecor = *img;
3702 -+
3703 -+ if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) {
3704 -+ redraw_screen(vc, 0);
3705 -+ update_region(vc, vc->vc_origin +
3706 -+ vc->vc_size_row * vc->vc_top,
3707 -+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
3708 -+ fbcon_decor_clear_margins(vc, info, 0);
3709 -+ }
3710 -+
3711 -+ if (origin == FBCON_DECOR_IO_ORIG_USER)
3712 -+ release_console_sem();
3713 -+
3714 -+ return 0;
3715 -+
3716 -+out: if (img->cmap.red)
3717 -+ vfree(img->cmap.red);
3718 -+
3719 -+ if (tmp)
3720 -+ vfree(tmp);
3721 -+ return -ENOMEM;
3722 -+}
3723 -+
3724 -+static int fbcon_decor_ioctl(struct inode * inode, struct file *filp, u_int cmd,
3725 -+ u_long arg)
3726 -+{
3727 -+ struct fbcon_decor_iowrapper __user *wrapper = (void __user*) arg;
3728 -+ struct vc_data *vc = NULL;
3729 -+ unsigned short vc_num = 0;
3730 -+ unsigned char origin = 0;
3731 -+ void __user *data = NULL;
3732 -+
3733 -+ if (!access_ok(VERIFY_READ, wrapper,
3734 -+ sizeof(struct fbcon_decor_iowrapper)))
3735 -+ return -EFAULT;
3736 -+
3737 -+ __get_user(vc_num, &wrapper->vc);
3738 -+ __get_user(origin, &wrapper->origin);
3739 -+ __get_user(data, &wrapper->data);
3740 -+
3741 -+ if (!vc_cons_allocated(vc_num))
3742 -+ return -EINVAL;
3743 -+
3744 -+ vc = vc_cons[vc_num].d;
3745 -+
3746 -+ switch (cmd) {
3747 -+ case FBIOCONDECOR_SETPIC:
3748 -+ {
3749 -+ struct fb_image img;
3750 -+ if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image)))
3751 -+ return -EFAULT;
3752 -+
3753 -+ return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
3754 -+ }
3755 -+ case FBIOCONDECOR_SETCFG:
3756 -+ {
3757 -+ struct vc_decor cfg;
3758 -+ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
3759 -+ return -EFAULT;
3760 -+
3761 -+ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
3762 -+ }
3763 -+ case FBIOCONDECOR_GETCFG:
3764 -+ {
3765 -+ int rval;
3766 -+ struct vc_decor cfg;
3767 -+
3768 -+ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
3769 -+ return -EFAULT;
3770 -+
3771 -+ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
3772 -+
3773 -+ if (copy_to_user(data, &cfg, sizeof(struct vc_decor)))
3774 -+ return -EFAULT;
3775 -+ return rval;
3776 -+ }
3777 -+ case FBIOCONDECOR_SETSTATE:
3778 -+ {
3779 -+ unsigned int state = 0;
3780 -+ if (get_user(state, (unsigned int __user *)data))
3781 -+ return -EFAULT;
3782 -+ return fbcon_decor_ioctl_dosetstate(vc, state, origin);
3783 -+ }
3784 -+ case FBIOCONDECOR_GETSTATE:
3785 -+ {
3786 -+ unsigned int state = 0;
3787 -+ fbcon_decor_ioctl_dogetstate(vc, &state);
3788 -+ return put_user(state, (unsigned int __user *)data);
3789 -+ }
3790 -+
3791 -+ default:
3792 -+ return -ENOIOCTLCMD;
3793 -+ }
3794 -+}
3795 -+
3796 -+#ifdef CONFIG_COMPAT
3797 -+
3798 -+static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
3799 -+
3800 -+ struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg;
3801 -+ struct vc_data *vc = NULL;
3802 -+ unsigned short vc_num = 0;
3803 -+ unsigned char origin = 0;
3804 -+ compat_uptr_t data_compat = 0;
3805 -+ void __user *data = NULL;
3806 -+
3807 -+ if (!access_ok(VERIFY_READ, wrapper,
3808 -+ sizeof(struct fbcon_decor_iowrapper32)))
3809 -+ return -EFAULT;
3810 -+
3811 -+ __get_user(vc_num, &wrapper->vc);
3812 -+ __get_user(origin, &wrapper->origin);
3813 -+ __get_user(data_compat, &wrapper->data);
3814 -+ data = compat_ptr(data_compat);
3815 -+
3816 -+ if (!vc_cons_allocated(vc_num))
3817 -+ return -EINVAL;
3818 -+
3819 -+ vc = vc_cons[vc_num].d;
3820 -+
3821 -+ switch (cmd) {
3822 -+ case FBIOCONDECOR_SETPIC32:
3823 -+ {
3824 -+ struct fb_image32 img_compat;
3825 -+ struct fb_image img;
3826 -+
3827 -+ if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32)))
3828 -+ return -EFAULT;
3829 -+
3830 -+ fb_image_from_compat(img, img_compat);
3831 -+
3832 -+ return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
3833 -+ }
3834 -+
3835 -+ case FBIOCONDECOR_SETCFG32:
3836 -+ {
3837 -+ struct vc_decor32 cfg_compat;
3838 -+ struct vc_decor cfg;
3839 -+
3840 -+ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
3841 -+ return -EFAULT;
3842 -+
3843 -+ vc_decor_from_compat(cfg, cfg_compat);
3844 -+
3845 -+ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
3846 -+ }
3847 -+
3848 -+ case FBIOCONDECOR_GETCFG32:
3849 -+ {
3850 -+ int rval;
3851 -+ struct vc_decor32 cfg_compat;
3852 -+ struct vc_decor cfg;
3853 -+
3854 -+ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
3855 -+ return -EFAULT;
3856 -+ cfg.theme = compat_ptr(cfg_compat.theme);
3857 -+
3858 -+ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
3859 -+
3860 -+ vc_decor_to_compat(cfg_compat, cfg);
3861 -+
3862 -+ if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32)))
3863 -+ return -EFAULT;
3864 -+ return rval;
3865 -+ }
3866 -+
3867 -+ case FBIOCONDECOR_SETSTATE32:
3868 -+ {
3869 -+ compat_uint_t state_compat = 0;
3870 -+ unsigned int state = 0;
3871 -+
3872 -+ if (get_user(state_compat, (compat_uint_t __user *)data))
3873 -+ return -EFAULT;
3874 -+
3875 -+ state = (unsigned int)state_compat;
3876 -+
3877 -+ return fbcon_decor_ioctl_dosetstate(vc, state, origin);
3878 -+ }
3879 -+
3880 -+ case FBIOCONDECOR_GETSTATE32:
3881 -+ {
3882 -+ compat_uint_t state_compat = 0;
3883 -+ unsigned int state = 0;
3884 -+
3885 -+ fbcon_decor_ioctl_dogetstate(vc, &state);
3886 -+ state_compat = (compat_uint_t)state;
3887 -+
3888 -+ return put_user(state_compat, (compat_uint_t __user *)data);
3889 -+ }
3890 -+
3891 -+ default:
3892 -+ return -ENOIOCTLCMD;
3893 -+ }
3894 -+}
3895 -+#else
3896 -+ #define fbcon_decor_compat_ioctl NULL
3897 -+#endif
3898 -+
3899 -+static struct file_operations fbcon_decor_ops = {
3900 -+ .owner = THIS_MODULE,
3901 -+ .ioctl = fbcon_decor_ioctl,
3902 -+ .compat_ioctl = fbcon_decor_compat_ioctl
3903 -+};
3904 -+
3905 -+static struct miscdevice fbcon_decor_dev = {
3906 -+ .minor = MISC_DYNAMIC_MINOR,
3907 -+ .name = "fbcondecor",
3908 -+ .fops = &fbcon_decor_ops
3909 -+};
3910 -+
3911 -+void fbcon_decor_reset(void)
3912 -+{
3913 -+ struct fb_info *info;
3914 -+ struct vc_data *vc;
3915 -+ int i;
3916 -+
3917 -+ vc = vc_cons[0].d;
3918 -+ info = registered_fb[0];
3919 -+
3920 -+ for (i = 0; i < num_registered_fb; i++) {
3921 -+ registered_fb[i]->bgdecor.data = NULL;
3922 -+ registered_fb[i]->bgdecor.cmap.red = NULL;
3923 -+ }
3924 -+
3925 -+ for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
3926 -+ vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth =
3927 -+ vc_cons[i].d->vc_decor.theight = 0;
3928 -+ vc_cons[i].d->vc_decor.theme = NULL;
3929 -+ }
3930 -+
3931 -+ return;
3932 -+}
3933 -+
3934 -+int fbcon_decor_init(void)
3935 -+{
3936 -+ int i;
3937 -+
3938 -+ fbcon_decor_reset();
3939 -+
3940 -+ if (initialized)
3941 -+ return 0;
3942 -+
3943 -+ i = misc_register(&fbcon_decor_dev);
3944 -+ if (i) {
3945 -+ printk(KERN_ERR "fbcondecor: failed to register device\n");
3946 -+ return i;
3947 -+ }
3948 -+
3949 -+ fbcon_decor_call_helper("init", 0);
3950 -+ initialized = 1;
3951 -+ return 0;
3952 -+}
3953 -+
3954 -+int fbcon_decor_exit(void)
3955 -+{
3956 -+ fbcon_decor_reset();
3957 -+ return 0;
3958 -+}
3959 -+
3960 -+EXPORT_SYMBOL(fbcon_decor_path);
3961 -diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h
3962 -new file mode 100644
3963 -index 0000000..1d852dd
3964 ---- /dev/null
3965 -+++ b/drivers/video/console/fbcondecor.h
3966 -@@ -0,0 +1,78 @@
3967 -+/*
3968 -+ * linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers
3969 -+ *
3970 -+ * Copyright (C) 2004 Michal Januszewski <spock@g.o>
3971 -+ *
3972 -+ */
3973 -+
3974 -+#ifndef __FBCON_DECOR_H
3975 -+#define __FBCON_DECOR_H
3976 -+
3977 -+#ifndef _LINUX_FB_H
3978 -+#include <linux/fb.h>
3979 -+#endif
3980 -+
3981 -+/* This is needed for vc_cons in fbcmap.c */
3982 -+#include <linux/vt_kern.h>
3983 -+
3984 -+struct fb_cursor;
3985 -+struct fb_info;
3986 -+struct vc_data;
3987 -+
3988 -+#ifdef CONFIG_FB_CON_DECOR
3989 -+/* fbcondecor.c */
3990 -+int fbcon_decor_init(void);
3991 -+int fbcon_decor_exit(void);
3992 -+int fbcon_decor_call_helper(char* cmd, unsigned short cons);
3993 -+int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw);
3994 -+
3995 -+/* cfbcondecor.c */
3996 -+void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
3997 -+void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor);
3998 -+void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
3999 -+void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
4000 -+void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank);
4001 -+void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
4002 -+void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
4003 -+void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
4004 -+
4005 -+/* vt.c */
4006 -+void acquire_console_sem(void);
4007 -+void release_console_sem(void);
4008 -+void do_unblank_screen(int entering_gfx);
4009 -+
4010 -+/* struct vc_data *y */
4011 -+#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme)
4012 -+
4013 -+/* struct fb_info *x, struct vc_data *y */
4014 -+#define fbcon_decor_active_nores(x,y) (x->bgdecor.data && fbcon_decor_active_vc(y))
4015 -+
4016 -+/* struct fb_info *x, struct vc_data *y */
4017 -+#define fbcon_decor_active(x,y) (fbcon_decor_active_nores(x,y) && \
4018 -+ x->bgdecor.width == x->var.xres && \
4019 -+ x->bgdecor.height == x->var.yres && \
4020 -+ x->bgdecor.depth == x->var.bits_per_pixel)
4021 -+
4022 -+
4023 -+#else /* CONFIG_FB_CON_DECOR */
4024 -+
4025 -+static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
4026 -+static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
4027 -+static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
4028 -+static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
4029 -+static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
4030 -+static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
4031 -+static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
4032 -+static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
4033 -+static inline int fbcon_decor_call_helper(char* cmd, unsigned short cons) { return 0; }
4034 -+static inline int fbcon_decor_init(void) { return 0; }
4035 -+static inline int fbcon_decor_exit(void) { return 0; }
4036 -+static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
4037 -+
4038 -+#define fbcon_decor_active_vc(y) (0)
4039 -+#define fbcon_decor_active_nores(x,y) (0)
4040 -+#define fbcon_decor_active(x,y) (0)
4041 -+
4042 -+#endif /* CONFIG_FB_CON_DECOR */
4043 -+
4044 -+#endif /* __FBCON_DECOR_H */
4045 -diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
4046 -index f53b9f1..467f921 100644
4047 ---- a/drivers/video/fbcmap.c
4048 -+++ b/drivers/video/fbcmap.c
4049 -@@ -17,6 +17,8 @@
4050 - #include <linux/slab.h>
4051 - #include <linux/uaccess.h>
4052 -
4053 -+#include "console/fbcondecor.h"
4054 -+
4055 - static u16 red2[] __read_mostly = {
4056 - 0x0000, 0xaaaa
4057 - };
4058 -@@ -234,14 +236,17 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
4059 - if (transp)
4060 - htransp = *transp++;
4061 - if (info->fbops->fb_setcolreg(start++,
4062 -- hred, hgreen, hblue,
4063 -+ hred, hgreen, hblue,
4064 - htransp, info))
4065 - break;
4066 - }
4067 - }
4068 -- if (rc == 0)
4069 -+ if (rc == 0) {
4070 - fb_copy_cmap(cmap, &info->cmap);
4071 --
4072 -+ if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
4073 -+ info->fix.visual == FB_VISUAL_DIRECTCOLOR)
4074 -+ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
4075 -+ }
4076 - return rc;
4077 - }
4078 -
4079 -diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
4080 -index a85c818..1f1c24b 100644
4081 ---- a/drivers/video/fbmem.c
4082 -+++ b/drivers/video/fbmem.c
4083 -@@ -1173,15 +1173,6 @@ struct fb_fix_screeninfo32 {
4084 - u16 reserved[3];
4085 - };
4086 -
4087 --struct fb_cmap32 {
4088 -- u32 start;
4089 -- u32 len;
4090 -- compat_caddr_t red;
4091 -- compat_caddr_t green;
4092 -- compat_caddr_t blue;
4093 -- compat_caddr_t transp;
4094 --};
4095 --
4096 - static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
4097 - unsigned long arg)
4098 - {
4099 -diff --git a/include/linux/console_decor.h b/include/linux/console_decor.h
4100 -new file mode 100644
4101 -index 0000000..04b8d80
4102 ---- /dev/null
4103 -+++ b/include/linux/console_decor.h
4104 -@@ -0,0 +1,46 @@
4105 -+#ifndef _LINUX_CONSOLE_DECOR_H_
4106 -+#define _LINUX_CONSOLE_DECOR_H_ 1
4107 -+
4108 -+/* A structure used by the framebuffer console decorations (drivers/video/console/fbcondecor.c) */
4109 -+struct vc_decor {
4110 -+ __u8 bg_color; /* The color that is to be treated as transparent */
4111 -+ __u8 state; /* Current decor state: 0 = off, 1 = on */
4112 -+ __u16 tx, ty; /* Top left corner coordinates of the text field */
4113 -+ __u16 twidth, theight; /* Width and height of the text field */
4114 -+ char* theme;
4115 -+};
4116 -+
4117 -+#ifdef __KERNEL__
4118 -+#ifdef CONFIG_COMPAT
4119 -+#include <linux/compat.h>
4120 -+
4121 -+struct vc_decor32 {
4122 -+ __u8 bg_color; /* The color that is to be treated as transparent */
4123 -+ __u8 state; /* Current decor state: 0 = off, 1 = on */
4124 -+ __u16 tx, ty; /* Top left corner coordinates of the text field */
4125 -+ __u16 twidth, theight; /* Width and height of the text field */
4126 -+ compat_uptr_t theme;
4127 -+};
4128 -+
4129 -+#define vc_decor_from_compat(to, from) \
4130 -+ (to).bg_color = (from).bg_color; \
4131 -+ (to).state = (from).state; \
4132 -+ (to).tx = (from).tx; \
4133 -+ (to).ty = (from).ty; \
4134 -+ (to).twidth = (from).twidth; \
4135 -+ (to).theight = (from).theight; \
4136 -+ (to).theme = compat_ptr((from).theme)
4137 -+
4138 -+#define vc_decor_to_compat(to, from) \
4139 -+ (to).bg_color = (from).bg_color; \
4140 -+ (to).state = (from).state; \
4141 -+ (to).tx = (from).tx; \
4142 -+ (to).ty = (from).ty; \
4143 -+ (to).twidth = (from).twidth; \
4144 -+ (to).theight = (from).theight; \
4145 -+ (to).theme = ptr_to_compat((from).theme)
4146 -+
4147 -+#endif /* CONFIG_COMPAT */
4148 -+#endif /* __KERNEL__ */
4149 -+
4150 -+#endif
4151 -diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
4152 -index 38fe59d..8e4058b 100644
4153 ---- a/include/linux/console_struct.h
4154 -+++ b/include/linux/console_struct.h
4155 -@@ -19,6 +19,7 @@
4156 - struct vt_struct;
4157 -
4158 - #define NPAR 16
4159 -+#include <linux/console_decor.h>
4160 -
4161 - struct vc_data {
4162 - unsigned short vc_num; /* Console number */
4163 -@@ -105,6 +106,8 @@ struct vc_data {
4164 - struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */
4165 - unsigned long vc_uni_pagedir;
4166 - unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
4167 -+
4168 -+ struct vc_decor vc_decor;
4169 - /* additional information is in vt_kern.h */
4170 - };
4171 -
4172 -diff --git a/include/linux/fb.h b/include/linux/fb.h
4173 -index f847df9..7ac118e 100644
4174 ---- a/include/linux/fb.h
4175 -+++ b/include/linux/fb.h
4176 -@@ -3,13 +3,31 @@
4177 -
4178 - #include <linux/types.h>
4179 - #include <linux/i2c.h>
4180 --
4181 - struct dentry;
4182 -
4183 - /* Definitions of frame buffers */
4184 -
4185 - #define FB_MAX 32 /* sufficient for now */
4186 -
4187 -+struct fbcon_decor_iowrapper
4188 -+{
4189 -+ unsigned short vc; /* Virtual console */
4190 -+ unsigned char origin; /* Point of origin of the request */
4191 -+ void *data;
4192 -+};
4193 -+
4194 -+#ifdef __KERNEL__
4195 -+#ifdef CONFIG_COMPAT
4196 -+#include <linux/compat.h>
4197 -+struct fbcon_decor_iowrapper32
4198 -+{
4199 -+ unsigned short vc; /* Virtual console */
4200 -+ unsigned char origin; /* Point of origin of the request */
4201 -+ compat_uptr_t data;
4202 -+};
4203 -+#endif /* CONFIG_COMPAT */
4204 -+#endif /* __KERNEL__ */
4205 -+
4206 - /* ioctls
4207 - 0x46 is 'F' */
4208 - #define FBIOGET_VSCREENINFO 0x4600
4209 -@@ -37,7 +55,24 @@ struct dentry;
4210 - #define FBIOGET_HWCINFO 0x4616
4211 - #define FBIOPUT_MODEINFO 0x4617
4212 - #define FBIOGET_DISPINFO 0x4618
4213 -+#define FBIOCONDECOR_SETCFG _IOWR('F', 0x19, struct fbcon_decor_iowrapper)
4214 -+#define FBIOCONDECOR_GETCFG _IOR('F', 0x1A, struct fbcon_decor_iowrapper)
4215 -+#define FBIOCONDECOR_SETSTATE _IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
4216 -+#define FBIOCONDECOR_GETSTATE _IOR('F', 0x1C, struct fbcon_decor_iowrapper)
4217 -+#define FBIOCONDECOR_SETPIC _IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
4218 -+#ifdef __KERNEL__
4219 -+#ifdef CONFIG_COMPAT
4220 -+#define FBIOCONDECOR_SETCFG32 _IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
4221 -+#define FBIOCONDECOR_GETCFG32 _IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
4222 -+#define FBIOCONDECOR_SETSTATE32 _IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
4223 -+#define FBIOCONDECOR_GETSTATE32 _IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
4224 -+#define FBIOCONDECOR_SETPIC32 _IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
4225 -+#endif /* CONFIG_COMPAT */
4226 -+#endif /* __KERNEL__ */
4227 -
4228 -+#define FBCON_DECOR_THEME_LEN 128 /* Maximum lenght of a theme name */
4229 -+#define FBCON_DECOR_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */
4230 -+#define FBCON_DECOR_IO_ORIG_USER 1 /* User ioctl origin */
4231 -
4232 - #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
4233 - #define FB_TYPE_PLANES 1 /* Non interleaved planes */
4234 -@@ -281,6 +316,28 @@ struct fb_cmap {
4235 - __u16 *transp; /* transparency, can be NULL */
4236 - };
4237 -
4238 -+#ifdef __KERNEL__
4239 -+#ifdef CONFIG_COMPAT
4240 -+struct fb_cmap32 {
4241 -+ __u32 start;
4242 -+ __u32 len; /* Number of entries */
4243 -+ compat_uptr_t red; /* Red values */
4244 -+ compat_uptr_t green;
4245 -+ compat_uptr_t blue;
4246 -+ compat_uptr_t transp; /* transparency, can be NULL */
4247 -+};
4248 -+
4249 -+#define fb_cmap_from_compat(to, from) \
4250 -+ (to).start = (from).start; \
4251 -+ (to).len = (from).len; \
4252 -+ (to).red = compat_ptr((from).red); \
4253 -+ (to).green = compat_ptr((from).green); \
4254 -+ (to).blue = compat_ptr((from).blue); \
4255 -+ (to).transp = compat_ptr((from).transp)
4256 -+
4257 -+#endif /* CONFIG_COMPAT */
4258 -+#endif /* __KERNEL__ */
4259 -+
4260 - struct fb_con2fbmap {
4261 - __u32 console;
4262 - __u32 framebuffer;
4263 -@@ -362,6 +419,34 @@ struct fb_image {
4264 - struct fb_cmap cmap; /* color map info */
4265 - };
4266 -
4267 -+#ifdef __KERNEL__
4268 -+#ifdef CONFIG_COMPAT
4269 -+struct fb_image32 {
4270 -+ __u32 dx; /* Where to place image */
4271 -+ __u32 dy;
4272 -+ __u32 width; /* Size of image */
4273 -+ __u32 height;
4274 -+ __u32 fg_color; /* Only used when a mono bitmap */
4275 -+ __u32 bg_color;
4276 -+ __u8 depth; /* Depth of the image */
4277 -+ const compat_uptr_t data; /* Pointer to image data */
4278 -+ struct fb_cmap32 cmap; /* color map info */
4279 -+};
4280 -+
4281 -+#define fb_image_from_compat(to, from) \
4282 -+ (to).dx = (from).dx; \
4283 -+ (to).dy = (from).dy; \
4284 -+ (to).width = (from).width; \
4285 -+ (to).height = (from).height; \
4286 -+ (to).fg_color = (from).fg_color; \
4287 -+ (to).bg_color = (from).bg_color; \
4288 -+ (to).depth = (from).depth; \
4289 -+ (to).data = compat_ptr((from).data); \
4290 -+ fb_cmap_from_compat((to).cmap, (from).cmap)
4291 -+
4292 -+#endif /* CONFIG_COMPAT */
4293 -+#endif /* __KERNEL__ */
4294 -+
4295 - /*
4296 - * hardware cursor control
4297 - */
4298 -@@ -859,6 +944,9 @@ struct fb_info {
4299 - #define FBINFO_STATE_SUSPENDED 1
4300 - u32 state; /* Hardware state i.e suspend */
4301 - void *fbcon_par; /* fbcon use-only private area */
4302 -+
4303 -+ struct fb_image bgdecor;
4304 -+
4305 - /* From here on everything is device dependent */
4306 - void *par;
4307 - /* we need the PCI or similiar aperture base/size not
4308 -diff --git a/kernel/sysctl.c b/kernel/sysctl.c
4309 -index 98e0232..24f4e31 100644
4310 ---- a/kernel/sysctl.c
4311 -+++ b/kernel/sysctl.c
4312 -@@ -118,6 +118,9 @@ static int ngroups_max = NGROUPS_MAX;
4313 - extern char modprobe_path[];
4314 - extern int modules_disabled;
4315 - #endif
4316 -+#ifdef CONFIG_FB_CON_DECOR
4317 -+extern char fbcon_decor_path[];
4318 -+#endif
4319 - #ifdef CONFIG_CHR_DEV_SG
4320 - extern int sg_big_buff;
4321 - #endif
4322 -@@ -230,6 +233,18 @@ static struct ctl_table root_table[] = {
4323 - .mode = 0555,
4324 - .child = dev_table,
4325 - },
4326 -+#ifdef CONFIG_FB_CON_DECOR
4327 -+ {
4328 -+ .ctl_name = CTL_UNNUMBERED,
4329 -+ .procname = "fbcondecor",
4330 -+ .data = &fbcon_decor_path,
4331 -+ .maxlen = KMOD_PATH_LEN,
4332 -+ .mode = 0644,
4333 -+ .proc_handler = &proc_dostring,
4334 -+ .strategy = &sysctl_string,
4335 -+ },
4336 -+#endif
4337 -+
4338 - /*
4339 - * NOTE: do not add new entries to this table unless you have read
4340 - * Documentation/sysctl/ctl_unnumbered.txt