Gentoo Archives: gentoo-commits

From: "Mike Pagano (mpagano)" <mpagano@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1916 - genpatches-2.6/trunk/2.6.39
Date: Wed, 18 May 2011 11:32:41
Message-Id: 20110518113227.C5CC420054@flycatcher.gentoo.org
1 Author: mpagano
2 Date: 2011-05-18 11:32:26 +0000 (Wed, 18 May 2011)
3 New Revision: 1916
4
5 Added:
6 genpatches-2.6/trunk/2.6.39/4200_fbcondecor-0.9.6.patch
7 Modified:
8 genpatches-2.6/trunk/2.6.39/0000_README
9 Log:
10 fbcondecor patch see: http://dev.gentoo.org/~spock/projects/fbcondecor/
11
12 Modified: genpatches-2.6/trunk/2.6.39/0000_README
13 ===================================================================
14 --- genpatches-2.6/trunk/2.6.39/0000_README 2011-05-16 17:32:13 UTC (rev 1915)
15 +++ genpatches-2.6/trunk/2.6.39/0000_README 2011-05-18 11:32:26 UTC (rev 1916)
16 @@ -39,3 +39,6 @@
17 Individual Patch Descriptions:
18 --------------------------------------------------------------------------
19
20 +Patch: 4200_fbcondecor-0.9.6.patch
21 +From: http://dev.gentoo.org/~spock
22 +Desc: Bootsplash successor by Michal Januszewski ported by Alexxy
23
24 Added: genpatches-2.6/trunk/2.6.39/4200_fbcondecor-0.9.6.patch
25 ===================================================================
26 --- genpatches-2.6/trunk/2.6.39/4200_fbcondecor-0.9.6.patch (rev 0)
27 +++ genpatches-2.6/trunk/2.6.39/4200_fbcondecor-0.9.6.patch 2011-05-18 11:32:26 UTC (rev 1916)
28 @@ -0,0 +1,2157 @@
29 +From cfc6b027203601fcbf0578380b7f5922dc6b2798 Mon Sep 17 00:00:00 2001
30 +From: Alexey Shvetsov <alexxy@g.o>
31 +Date: Sun, 23 Jan 2011 00:09:58 +0300
32 +Subject: [PATCH] [PATCH] [fbcondecor-0.9.6] Import fbcondecor
33 +
34 +Import from http://dev.gentoo.org/~spock
35 +Bootsplash successor by Michal Januszewski
36 +
37 +Signed-off-by: Alexey Shvetsov <alexxy@g.o>
38 +---
39 + Documentation/fb/00-INDEX | 2 +
40 + Documentation/fb/fbcondecor.txt | 206 +++++++++++++
41 + drivers/Makefile | 4 +-
42 + drivers/video/console/Kconfig | 13 +
43 + drivers/video/console/Makefile | 1 +
44 + drivers/video/console/bitblit.c | 20 +-
45 + drivers/video/console/cfbcondecor.c | 471 +++++++++++++++++++++++++++++
46 + drivers/video/console/fbcon.c | 186 ++++++++++--
47 + drivers/video/console/fbcondecor.c | 562 +++++++++++++++++++++++++++++++++++
48 + drivers/video/console/fbcondecor.h | 78 +++++
49 + drivers/video/fbcmap.c | 9 +-
50 + drivers/video/fbmem.c | 9 -
51 + include/linux/console_decor.h | 46 +++
52 + include/linux/console_struct.h | 3 +
53 + include/linux/fb.h | 88 ++++++
54 + kernel/sysctl.c | 13 +
55 + 16 files changed, 1670 insertions(+), 41 deletions(-)
56 + create mode 100644 Documentation/fb/fbcondecor.txt
57 + create mode 100644 drivers/video/console/cfbcondecor.c
58 + create mode 100644 drivers/video/console/fbcondecor.c
59 + create mode 100644 drivers/video/console/fbcondecor.h
60 + create mode 100644 include/linux/console_decor.h
61 +
62 +diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
63 +index 30a7054..9b6a733 100644
64 +--- a/Documentation/fb/00-INDEX
65 ++++ b/Documentation/fb/00-INDEX
66 +@@ -21,6 +21,8 @@ ep93xx-fb.txt
67 + - info on the driver for EP93xx LCD controller.
68 + fbcon.txt
69 + - intro to and usage guide for the framebuffer console (fbcon).
70 ++fbcondecor.txt
71 ++ - info on the Framebuffer Console Decoration
72 + framebuffer.txt
73 + - introduction to frame buffer devices.
74 + gxfb.txt
75 +diff --git a/Documentation/fb/fbcondecor.txt b/Documentation/fb/fbcondecor.txt
76 +new file mode 100644
77 +index 0000000..be435b5
78 +--- /dev/null
79 ++++ b/Documentation/fb/fbcondecor.txt
80 +@@ -0,0 +1,206 @@
81 ++What is it?
82 ++-----------
83 ++
84 ++The framebuffer decorations are a kernel feature which allows displaying a
85 ++background picture on selected consoles.
86 ++
87 ++What do I need to get it to work?
88 ++---------------------------------
89 ++
90 ++To get fbcondecor up-and-running you will have to:
91 ++ 1) get a copy of splashutils [1] or a similar program
92 ++ 2) get some fbcondecor themes
93 ++ 3) build the kernel helper program
94 ++ 4) build your kernel with the FB_CON_DECOR option enabled.
95 ++
96 ++To get fbcondecor operational right after fbcon initialization is finished, you
97 ++will have to include a theme and the kernel helper into your initramfs image.
98 ++Please refer to splashutils documentation for instructions on how to do that.
99 ++
100 ++[1] The splashutils package can be downloaded from:
101 ++ http://dev.gentoo.org/~spock/projects/splashutils/
102 ++
103 ++The userspace helper
104 ++--------------------
105 ++
106 ++The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the
107 ++kernel whenever an important event occurs and the kernel needs some kind of
108 ++job to be carried out. Important events include console switches and video
109 ++mode switches (the kernel requests background images and configuration
110 ++parameters for the current console). The fbcondecor helper must be accessible at
111 ++all times. If it's not, fbcondecor will be switched off automatically.
112 ++
113 ++It's possible to set path to the fbcondecor helper by writing it to
114 ++/proc/sys/kernel/fbcondecor.
115 ++
116 ++*****************************************************************************
117 ++
118 ++The information below is mostly technical stuff. There's probably no need to
119 ++read it unless you plan to develop a userspace helper.
120 ++
121 ++The fbcondecor protocol
122 ++-----------------------
123 ++
124 ++The fbcondecor protocol defines a communication interface between the kernel and
125 ++the userspace fbcondecor helper.
126 ++
127 ++The kernel side is responsible for:
128 ++
129 ++ * rendering console text, using an image as a background (instead of a
130 ++ standard solid color fbcon uses),
131 ++ * accepting commands from the user via ioctls on the fbcondecor device,
132 ++ * calling the userspace helper to set things up as soon as the fb subsystem
133 ++ is initialized.
134 ++
135 ++The userspace helper is responsible for everything else, including parsing
136 ++configuration files, decompressing the image files whenever the kernel needs
137 ++it, and communicating with the kernel if necessary.
138 ++
139 ++The fbcondecor protocol specifies how communication is done in both ways:
140 ++kernel->userspace and userspace->helper.
141 ++
142 ++Kernel -> Userspace
143 ++-------------------
144 ++
145 ++The kernel communicates with the userspace helper by calling it and specifying
146 ++the task to be done in a series of arguments.
147 ++
148 ++The arguments follow the pattern:
149 ++<fbcondecor protocol version> <command> <parameters>
150 ++
151 ++All commands defined in fbcondecor protocol v2 have the following parameters:
152 ++ virtual console
153 ++ framebuffer number
154 ++ theme
155 ++
156 ++Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the
157 ++framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used.
158 ++
159 ++Fbcondecor protocol v2 specifies the following commands:
160 ++
161 ++getpic
162 ++------
163 ++ The kernel issues this command to request image data. It's up to the
164 ++ userspace helper to find a background image appropriate for the specified
165 ++ theme and the current resolution. The userspace helper should respond by
166 ++ issuing the FBIOCONDECOR_SETPIC ioctl.
167 ++
168 ++init
169 ++----
170 ++ The kernel issues this command after the fbcondecor device is created and
171 ++ the fbcondecor interface is initialized. Upon receiving 'init', the userspace
172 ++ helper should parse the kernel command line (/proc/cmdline) or otherwise
173 ++ decide whether fbcondecor is to be activated.
174 ++
175 ++ To activate fbcondecor on the first console the helper should issue the
176 ++ FBIOCONDECOR_SETCFG, FBIOCONDECOR_SETPIC and FBIOCONDECOR_SETSTATE commands,
177 ++ in the above-mentioned order.
178 ++
179 ++ When the userspace helper is called in an early phase of the boot process
180 ++ (right after the initialization of fbcon), no filesystems will be mounted.
181 ++ The helper program should mount sysfs and then create the appropriate
182 ++ framebuffer, fbcondecor and tty0 devices (if they don't already exist) to get
183 ++ current display settings and to be able to communicate with the kernel side.
184 ++ It should probably also mount the procfs to be able to parse the kernel
185 ++ command line parameters.
186 ++
187 ++ Note that the console sem is not held when the kernel calls fbcondecor_helper
188 ++ with the 'init' command. The fbcondecor helper should perform all ioctls with
189 ++ origin set to FBCON_DECOR_IO_ORIG_USER.
190 ++
191 ++modechange
192 ++----------
193 ++ The kernel issues this command on a mode change. The helper's response should
194 ++ be similar to the response to the 'init' command. Note that this time the
195 ++ console sem is held and all ioctls must be performed with origin set to
196 ++ FBCON_DECOR_IO_ORIG_KERNEL.
197 ++
198 ++
199 ++Userspace -> Kernel
200 ++-------------------
201 ++
202 ++Userspace programs can communicate with fbcondecor via ioctls on the
203 ++fbcondecor device. These ioctls are to be used by both the userspace helper
204 ++(called only by the kernel) and userspace configuration tools (run by the users).
205 ++
206 ++The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL
207 ++when doing the appropriate ioctls. All userspace configuration tools should
208 ++use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin
209 ++field when performing ioctls from the kernel helper will most likely result
210 ++in a console deadlock.
211 ++
212 ++FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console
213 ++semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire
214 ++the console sem.
215 ++
216 ++The framebuffer console decoration provides the following ioctls (all defined in
217 ++linux/fb.h):
218 ++
219 ++FBIOCONDECOR_SETPIC
220 ++description: loads a background picture for a virtual console
221 ++argument: struct fbcon_decor_iowrapper*; data: struct fb_image*
222 ++notes:
223 ++If called for consoles other than the current foreground one, the picture data
224 ++will be ignored.
225 ++
226 ++If the current virtual console is running in a 8-bpp mode, the cmap substruct
227 ++of fb_image has to be filled appropriately: start should be set to 16 (first
228 ++16 colors are reserved for fbcon), len to a value <= 240 and red, green and
229 ++blue should point to valid cmap data. The transp field is ingored. The fields
230 ++dx, dy, bg_color, fg_color in fb_image are ignored as well.
231 ++
232 ++FBIOCONDECOR_SETCFG
233 ++description: sets the fbcondecor config for a virtual console
234 ++argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
235 ++notes: The structure has to be filled with valid data.
236 ++
237 ++FBIOCONDECOR_GETCFG
238 ++description: gets the fbcondecor config for a virtual console
239 ++argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
240 ++
241 ++FBIOCONDECOR_SETSTATE
242 ++description: sets the fbcondecor state for a virtual console
243 ++argument: struct fbcon_decor_iowrapper*; data: unsigned int*
244 ++ values: 0 = disabled, 1 = enabled.
245 ++
246 ++FBIOCONDECOR_GETSTATE
247 ++description: gets the fbcondecor state for a virtual console
248 ++argument: struct fbcon_decor_iowrapper*; data: unsigned int*
249 ++ values: as in FBIOCONDECOR_SETSTATE
250 ++
251 ++Info on used structures:
252 ++
253 ++Definition of struct vc_decor can be found in linux/console_decor.h. It's
254 ++heavily commented. Note that the 'theme' field should point to a string
255 ++no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is
256 ++performed, the theme field should point to a char buffer of length
257 ++FBCON_DECOR_THEME_LEN.
258 ++
259 ++Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h.
260 ++The fields in this struct have the following meaning:
261 ++
262 ++vc:
263 ++Virtual console number.
264 ++
265 ++origin:
266 ++Specifies if the ioctl is performed as a response to a kernel request. The
267 ++fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace
268 ++programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to
269 ++avoid console semaphore deadlocks.
270 ++
271 ++data:
272 ++Pointer to a data structure appropriate for the performed ioctl. Type of
273 ++the data struct is specified in the ioctls description.
274 ++
275 ++*****************************************************************************
276 ++
277 ++Credit
278 ++------
279 ++
280 ++Original 'bootsplash' project & implementation by:
281 ++ Volker Poplawski <volker@×××××××××.de>, Stefan Reinauer <stepan@××××.de>,
282 ++ Steffen Winterfeldt <snwint@××××.de>, Michael Schroeder <mls@××××.de>,
283 ++ Ken Wimer <wimer@××××.de>.
284 ++
285 ++Fbcondecor, fbcondecor protocol design, current implementation & docs by:
286 ++ Michal Januszewski <spock@g.o>
287 +diff --git a/drivers/Makefile b/drivers/Makefile
288 +index b423bb1..4ce76a6 100644
289 +--- a/drivers/Makefile
290 ++++ b/drivers/Makefile
291 +@@ -9,6 +9,9 @@ obj-y += gpio/
292 + obj-$(CONFIG_PCI) += pci/
293 + obj-$(CONFIG_PARISC) += parisc/
294 + obj-$(CONFIG_RAPIDIO) += rapidio/
295 ++# char/ comes before serial/ etc so that the VT console is the boot-time
296 ++# default.
297 ++obj-y += char/
298 + obj-y += video/
299 + obj-y += idle/
300 + obj-$(CONFIG_ACPI) += acpi/
301 +@@ -27,7 +30,6 @@ obj-$(CONFIG_REGULATOR) += regulator/
302 + # tty/ comes before char/ so that the VT console is the boot-time
303 + # default.
304 + obj-y += tty/
305 +-obj-y += char/
306 +
307 + # gpu/ comes after char for AGP vs DRM startup
308 + obj-y += gpu/
309 +diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
310 +index 2209e35..1c49f8e 100644
311 +--- a/drivers/video/console/Kconfig
312 ++++ b/drivers/video/console/Kconfig
313 +@@ -122,6 +122,19 @@ config FRAMEBUFFER_CONSOLE_ROTATION
314 + such that other users of the framebuffer will remain normally
315 + oriented.
316 +
317 ++config FB_CON_DECOR
318 ++ bool "Support for the Framebuffer Console Decorations"
319 ++ depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
320 ++ default n
321 ++ ---help---
322 ++ This option enables support for framebuffer console decorations which
323 ++ makes it possible to display images in the background of the system
324 ++ consoles. Note that userspace utilities are necessary in order to take
325 ++ advantage of these features. Refer to Documentation/fb/fbcondecor.txt
326 ++ for more information.
327 ++
328 ++ If unsure, say N.
329 ++
330 + config STI_CONSOLE
331 + bool "STI text console"
332 + depends on PARISC
333 +diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
334 +index a862e91..b0ef643 100644
335 +--- a/drivers/video/console/Makefile
336 ++++ b/drivers/video/console/Makefile
337 +@@ -34,6 +34,7 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
338 + fbcon_ccw.o
339 + endif
340 +
341 ++obj-$(CONFIG_FB_CON_DECOR) += fbcondecor.o cfbcondecor.o
342 + obj-$(CONFIG_FB_STI) += sticore.o font.o
343 +
344 + ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
345 +diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
346 +index 28b1a83..1ac86bd 100644
347 +--- a/drivers/video/console/bitblit.c
348 ++++ b/drivers/video/console/bitblit.c
349 +@@ -18,6 +18,7 @@
350 + #include <linux/console.h>
351 + #include <asm/types.h>
352 + #include "fbcon.h"
353 ++#include "fbcondecor.h"
354 +
355 + /*
356 + * Accelerated handlers.
357 +@@ -55,6 +56,13 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
358 + area.height = height * vc->vc_font.height;
359 + area.width = width * vc->vc_font.width;
360 +
361 ++ if (fbcon_decor_active(info, vc)) {
362 ++ area.sx += vc->vc_decor.tx;
363 ++ area.sy += vc->vc_decor.ty;
364 ++ area.dx += vc->vc_decor.tx;
365 ++ area.dy += vc->vc_decor.ty;
366 ++ }
367 ++
368 + info->fbops->fb_copyarea(info, &area);
369 + }
370 +
371 +@@ -380,11 +388,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
372 + cursor.image.depth = 1;
373 + cursor.rop = ROP_XOR;
374 +
375 +- if (info->fbops->fb_cursor)
376 +- err = info->fbops->fb_cursor(info, &cursor);
377 ++ if (fbcon_decor_active(info, vc)) {
378 ++ fbcon_decor_cursor(info, &cursor);
379 ++ } else {
380 ++ if (info->fbops->fb_cursor)
381 ++ err = info->fbops->fb_cursor(info, &cursor);
382 +
383 +- if (err)
384 +- soft_cursor(info, &cursor);
385 ++ if (err)
386 ++ soft_cursor(info, &cursor);
387 ++ }
388 +
389 + ops->cursor_reset = 0;
390 + }
391 +diff --git a/drivers/video/console/cfbcondecor.c b/drivers/video/console/cfbcondecor.c
392 +new file mode 100644
393 +index 0000000..fbf6cf2
394 +--- /dev/null
395 ++++ b/drivers/video/console/cfbcondecor.c
396 +@@ -0,0 +1,471 @@
397 ++/*
398 ++ * linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions
399 ++ *
400 ++ * Copyright (C) 2004 Michal Januszewski <spock@g.o>
401 ++ *
402 ++ * Code based upon "Bootdecor" (C) 2001-2003
403 ++ * Volker Poplawski <volker@×××××××××.de>,
404 ++ * Stefan Reinauer <stepan@××××.de>,
405 ++ * Steffen Winterfeldt <snwint@××××.de>,
406 ++ * Michael Schroeder <mls@××××.de>,
407 ++ * Ken Wimer <wimer@××××.de>.
408 ++ *
409 ++ * This file is subject to the terms and conditions of the GNU General Public
410 ++ * License. See the file COPYING in the main directory of this archive for
411 ++ * more details.
412 ++ */
413 ++#include <linux/module.h>
414 ++#include <linux/types.h>
415 ++#include <linux/fb.h>
416 ++#include <linux/selection.h>
417 ++#include <linux/slab.h>
418 ++#include <linux/vt_kern.h>
419 ++#include <asm/irq.h>
420 ++#include <asm/system.h>
421 ++
422 ++#include "fbcon.h"
423 ++#include "fbcondecor.h"
424 ++
425 ++#define parse_pixel(shift,bpp,type) \
426 ++ do { \
427 ++ if (d & (0x80 >> (shift))) \
428 ++ dd2[(shift)] = fgx; \
429 ++ else \
430 ++ dd2[(shift)] = transparent ? *(type *)decor_src : bgx; \
431 ++ decor_src += (bpp); \
432 ++ } while (0) \
433 ++
434 ++extern int get_color(struct vc_data *vc, struct fb_info *info,
435 ++ u16 c, int is_fg);
436 ++
437 ++void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc)
438 ++{
439 ++ int i, j, k;
440 ++ int minlen = min(min(info->var.red.length, info->var.green.length),
441 ++ info->var.blue.length);
442 ++ u32 col;
443 ++
444 ++ for (j = i = 0; i < 16; i++) {
445 ++ k = color_table[i];
446 ++
447 ++ col = ((vc->vc_palette[j++] >> (8-minlen))
448 ++ << info->var.red.offset);
449 ++ col |= ((vc->vc_palette[j++] >> (8-minlen))
450 ++ << info->var.green.offset);
451 ++ col |= ((vc->vc_palette[j++] >> (8-minlen))
452 ++ << info->var.blue.offset);
453 ++ ((u32 *)info->pseudo_palette)[k] = col;
454 ++ }
455 ++}
456 ++
457 ++void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height,
458 ++ int width, u8* src, u32 fgx, u32 bgx, u8 transparent)
459 ++{
460 ++ unsigned int x, y;
461 ++ u32 dd;
462 ++ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
463 ++ unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
464 ++ unsigned int ds = (ypos * info->var.xres + xpos) * bytespp;
465 ++ u16 dd2[4];
466 ++
467 ++ u8* decor_src = (u8 *)(info->bgdecor.data + ds);
468 ++ u8* dst = (u8 *)(info->screen_base + d);
469 ++
470 ++ if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
471 ++ return;
472 ++
473 ++ for (y = 0; y < height; y++) {
474 ++ switch (info->var.bits_per_pixel) {
475 ++
476 ++ case 32:
477 ++ for (x = 0; x < width; x++) {
478 ++
479 ++ if ((x & 7) == 0)
480 ++ d = *src++;
481 ++ if (d & 0x80)
482 ++ dd = fgx;
483 ++ else
484 ++ dd = transparent ?
485 ++ *(u32 *)decor_src : bgx;
486 ++
487 ++ d <<= 1;
488 ++ decor_src += 4;
489 ++ fb_writel(dd, dst);
490 ++ dst += 4;
491 ++ }
492 ++ break;
493 ++ case 24:
494 ++ for (x = 0; x < width; x++) {
495 ++
496 ++ if ((x & 7) == 0)
497 ++ d = *src++;
498 ++ if (d & 0x80)
499 ++ dd = fgx;
500 ++ else
501 ++ dd = transparent ?
502 ++ (*(u32 *)decor_src & 0xffffff) : bgx;
503 ++
504 ++ d <<= 1;
505 ++ decor_src += 3;
506 ++#ifdef __LITTLE_ENDIAN
507 ++ fb_writew(dd & 0xffff, dst);
508 ++ dst += 2;
509 ++ fb_writeb((dd >> 16), dst);
510 ++#else
511 ++ fb_writew(dd >> 8, dst);
512 ++ dst += 2;
513 ++ fb_writeb(dd & 0xff, dst);
514 ++#endif
515 ++ dst++;
516 ++ }
517 ++ break;
518 ++ case 16:
519 ++ for (x = 0; x < width; x += 2) {
520 ++ if ((x & 7) == 0)
521 ++ d = *src++;
522 ++
523 ++ parse_pixel(0, 2, u16);
524 ++ parse_pixel(1, 2, u16);
525 ++#ifdef __LITTLE_ENDIAN
526 ++ dd = dd2[0] | (dd2[1] << 16);
527 ++#else
528 ++ dd = dd2[1] | (dd2[0] << 16);
529 ++#endif
530 ++ d <<= 2;
531 ++ fb_writel(dd, dst);
532 ++ dst += 4;
533 ++ }
534 ++ break;
535 ++
536 ++ case 8:
537 ++ for (x = 0; x < width; x += 4) {
538 ++ if ((x & 7) == 0)
539 ++ d = *src++;
540 ++
541 ++ parse_pixel(0, 1, u8);
542 ++ parse_pixel(1, 1, u8);
543 ++ parse_pixel(2, 1, u8);
544 ++ parse_pixel(3, 1, u8);
545 ++
546 ++#ifdef __LITTLE_ENDIAN
547 ++ dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
548 ++#else
549 ++ dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
550 ++#endif
551 ++ d <<= 4;
552 ++ fb_writel(dd, dst);
553 ++ dst += 4;
554 ++ }
555 ++ }
556 ++
557 ++ dst += info->fix.line_length - width * bytespp;
558 ++ decor_src += (info->var.xres - width) * bytespp;
559 ++ }
560 ++}
561 ++
562 ++#define cc2cx(a) \
563 ++ ((info->fix.visual == FB_VISUAL_TRUECOLOR || \
564 ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \
565 ++ ((u32*)info->pseudo_palette)[a] : a)
566 ++
567 ++void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info,
568 ++ const unsigned short *s, int count, int yy, int xx)
569 ++{
570 ++ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
571 ++ struct fbcon_ops *ops = info->fbcon_par;
572 ++ int fg_color, bg_color, transparent;
573 ++ u8 *src;
574 ++ u32 bgx, fgx;
575 ++ u16 c = scr_readw(s);
576 ++
577 ++ fg_color = get_color(vc, info, c, 1);
578 ++ bg_color = get_color(vc, info, c, 0);
579 ++
580 ++ /* Don't paint the background image if console is blanked */
581 ++ transparent = ops->blank_state ? 0 :
582 ++ (vc->vc_decor.bg_color == bg_color);
583 ++
584 ++ xx = xx * vc->vc_font.width + vc->vc_decor.tx;
585 ++ yy = yy * vc->vc_font.height + vc->vc_decor.ty;
586 ++
587 ++ fgx = cc2cx(fg_color);
588 ++ bgx = cc2cx(bg_color);
589 ++
590 ++ while (count--) {
591 ++ c = scr_readw(s++);
592 ++ src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
593 ++ ((vc->vc_font.width + 7) >> 3);
594 ++
595 ++ fbcon_decor_renderc(info, yy, xx, vc->vc_font.height,
596 ++ vc->vc_font.width, src, fgx, bgx, transparent);
597 ++ xx += vc->vc_font.width;
598 ++ }
599 ++}
600 ++
601 ++void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor)
602 ++{
603 ++ int i;
604 ++ unsigned int dsize, s_pitch;
605 ++ struct fbcon_ops *ops = info->fbcon_par;
606 ++ struct vc_data* vc;
607 ++ u8 *src;
608 ++
609 ++ /* we really don't need any cursors while the console is blanked */
610 ++ if (info->state != FBINFO_STATE_RUNNING || ops->blank_state)
611 ++ return;
612 ++
613 ++ vc = vc_cons[ops->currcon].d;
614 ++
615 ++ src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC);
616 ++ if (!src)
617 ++ return;
618 ++
619 ++ s_pitch = (cursor->image.width + 7) >> 3;
620 ++ dsize = s_pitch * cursor->image.height;
621 ++ if (cursor->enable) {
622 ++ switch (cursor->rop) {
623 ++ case ROP_XOR:
624 ++ for (i = 0; i < dsize; i++)
625 ++ src[i] = cursor->image.data[i] ^ cursor->mask[i];
626 ++ break;
627 ++ case ROP_COPY:
628 ++ default:
629 ++ for (i = 0; i < dsize; i++)
630 ++ src[i] = cursor->image.data[i] & cursor->mask[i];
631 ++ break;
632 ++ }
633 ++ } else
634 ++ memcpy(src, cursor->image.data, dsize);
635 ++
636 ++ fbcon_decor_renderc(info,
637 ++ cursor->image.dy + vc->vc_decor.ty,
638 ++ cursor->image.dx + vc->vc_decor.tx,
639 ++ cursor->image.height,
640 ++ cursor->image.width,
641 ++ (u8*)src,
642 ++ cc2cx(cursor->image.fg_color),
643 ++ cc2cx(cursor->image.bg_color),
644 ++ cursor->image.bg_color == vc->vc_decor.bg_color);
645 ++
646 ++ kfree(src);
647 ++}
648 ++
649 ++static void decorset(u8 *dst, int height, int width, int dstbytes,
650 ++ u32 bgx, int bpp)
651 ++{
652 ++ int i;
653 ++
654 ++ if (bpp == 8)
655 ++ bgx |= bgx << 8;
656 ++ if (bpp == 16 || bpp == 8)
657 ++ bgx |= bgx << 16;
658 ++
659 ++ while (height-- > 0) {
660 ++ u8 *p = dst;
661 ++
662 ++ switch (bpp) {
663 ++
664 ++ case 32:
665 ++ for (i=0; i < width; i++) {
666 ++ fb_writel(bgx, p); p += 4;
667 ++ }
668 ++ break;
669 ++ case 24:
670 ++ for (i=0; i < width; i++) {
671 ++#ifdef __LITTLE_ENDIAN
672 ++ fb_writew((bgx & 0xffff),(u16*)p); p += 2;
673 ++ fb_writeb((bgx >> 16),p++);
674 ++#else
675 ++ fb_writew((bgx >> 8),(u16*)p); p += 2;
676 ++ fb_writeb((bgx & 0xff),p++);
677 ++#endif
678 ++ }
679 ++ case 16:
680 ++ for (i=0; i < width/4; i++) {
681 ++ fb_writel(bgx,p); p += 4;
682 ++ fb_writel(bgx,p); p += 4;
683 ++ }
684 ++ if (width & 2) {
685 ++ fb_writel(bgx,p); p += 4;
686 ++ }
687 ++ if (width & 1)
688 ++ fb_writew(bgx,(u16*)p);
689 ++ break;
690 ++ case 8:
691 ++ for (i=0; i < width/4; i++) {
692 ++ fb_writel(bgx,p); p += 4;
693 ++ }
694 ++
695 ++ if (width & 2) {
696 ++ fb_writew(bgx,p); p += 2;
697 ++ }
698 ++ if (width & 1)
699 ++ fb_writeb(bgx,(u8*)p);
700 ++ break;
701 ++
702 ++ }
703 ++ dst += dstbytes;
704 ++ }
705 ++}
706 ++
707 ++void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
708 ++ int srclinebytes, int bpp)
709 ++{
710 ++ int i;
711 ++
712 ++ while (height-- > 0) {
713 ++ u32 *p = (u32 *)dst;
714 ++ u32 *q = (u32 *)src;
715 ++
716 ++ switch (bpp) {
717 ++
718 ++ case 32:
719 ++ for (i=0; i < width; i++)
720 ++ fb_writel(*q++, p++);
721 ++ break;
722 ++ case 24:
723 ++ for (i=0; i < (width*3/4); i++)
724 ++ fb_writel(*q++, p++);
725 ++ if ((width*3) % 4) {
726 ++ if (width & 2) {
727 ++ fb_writeb(*(u8*)q, (u8*)p);
728 ++ } else if (width & 1) {
729 ++ fb_writew(*(u16*)q, (u16*)p);
730 ++ fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2));
731 ++ }
732 ++ }
733 ++ break;
734 ++ case 16:
735 ++ for (i=0; i < width/4; i++) {
736 ++ fb_writel(*q++, p++);
737 ++ fb_writel(*q++, p++);
738 ++ }
739 ++ if (width & 2)
740 ++ fb_writel(*q++, p++);
741 ++ if (width & 1)
742 ++ fb_writew(*(u16*)q, (u16*)p);
743 ++ break;
744 ++ case 8:
745 ++ for (i=0; i < width/4; i++)
746 ++ fb_writel(*q++, p++);
747 ++
748 ++ if (width & 2) {
749 ++ fb_writew(*(u16*)q, (u16*)p);
750 ++ q = (u32*) ((u16*)q + 1);
751 ++ p = (u32*) ((u16*)p + 1);
752 ++ }
753 ++ if (width & 1)
754 ++ fb_writeb(*(u8*)q, (u8*)p);
755 ++ break;
756 ++ }
757 ++
758 ++ dst += linebytes;
759 ++ src += srclinebytes;
760 ++ }
761 ++}
762 ++
763 ++static void decorfill(struct fb_info *info, int sy, int sx, int height,
764 ++ int width)
765 ++{
766 ++ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
767 ++ int d = sy * info->fix.line_length + sx * bytespp;
768 ++ int ds = (sy * info->var.xres + sx) * bytespp;
769 ++
770 ++ fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds),
771 ++ height, width, info->fix.line_length, info->var.xres * bytespp,
772 ++ info->var.bits_per_pixel);
773 ++}
774 ++
775 ++void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
776 ++ int height, int width)
777 ++{
778 ++ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
779 ++ struct fbcon_ops *ops = info->fbcon_par;
780 ++ u8 *dst;
781 ++ int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info);
782 ++
783 ++ transparent = (vc->vc_decor.bg_color == bg_color);
784 ++ sy = sy * vc->vc_font.height + vc->vc_decor.ty;
785 ++ sx = sx * vc->vc_font.width + vc->vc_decor.tx;
786 ++ height *= vc->vc_font.height;
787 ++ width *= vc->vc_font.width;
788 ++
789 ++ /* Don't paint the background image if console is blanked */
790 ++ if (transparent && !ops->blank_state) {
791 ++ decorfill(info, sy, sx, height, width);
792 ++ } else {
793 ++ dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
794 ++ sx * ((info->var.bits_per_pixel + 7) >> 3));
795 ++ decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
796 ++ info->var.bits_per_pixel);
797 ++ }
798 ++}
799 ++
800 ++void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info,
801 ++ int bottom_only)
802 ++{
803 ++ unsigned int tw = vc->vc_cols*vc->vc_font.width;
804 ++ unsigned int th = vc->vc_rows*vc->vc_font.height;
805 ++
806 ++ if (!bottom_only) {
807 ++ /* top margin */
808 ++ decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres);
809 ++ /* left margin */
810 ++ decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx);
811 ++ /* right margin */
812 ++ decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th,
813 ++ info->var.xres - vc->vc_decor.tx - tw);
814 ++ }
815 ++ decorfill(info, vc->vc_decor.ty + th, 0,
816 ++ info->var.yres - vc->vc_decor.ty - th, info->var.xres);
817 ++}
818 ++
819 ++void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y,
820 ++ int sx, int dx, int width)
821 ++{
822 ++ u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
823 ++ u16 *s = d + (dx - sx);
824 ++ u16 *start = d;
825 ++ u16 *ls = d;
826 ++ u16 *le = d + width;
827 ++ u16 c;
828 ++ int x = dx;
829 ++ u16 attr = 1;
830 ++
831 ++ do {
832 ++ c = scr_readw(d);
833 ++ if (attr != (c & 0xff00)) {
834 ++ attr = c & 0xff00;
835 ++ if (d > start) {
836 ++ fbcon_decor_putcs(vc, info, start, d - start, y, x);
837 ++ x += d - start;
838 ++ start = d;
839 ++ }
840 ++ }
841 ++ if (s >= ls && s < le && c == scr_readw(s)) {
842 ++ if (d > start) {
843 ++ fbcon_decor_putcs(vc, info, start, d - start, y, x);
844 ++ x += d - start + 1;
845 ++ start = d + 1;
846 ++ } else {
847 ++ x++;
848 ++ start++;
849 ++ }
850 ++ }
851 ++ s++;
852 ++ d++;
853 ++ } while (d < le);
854 ++ if (d > start)
855 ++ fbcon_decor_putcs(vc, info, start, d - start, y, x);
856 ++}
857 ++
858 ++void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank)
859 ++{
860 ++ if (blank) {
861 ++ decorset((u8 *)info->screen_base, info->var.yres, info->var.xres,
862 ++ info->fix.line_length, 0, info->var.bits_per_pixel);
863 ++ } else {
864 ++ update_screen(vc);
865 ++ fbcon_decor_clear_margins(vc, info, 0);
866 ++ }
867 ++}
868 +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
869 +index 9c092b8..e763778 100644
870 +--- a/drivers/video/console/fbcon.c
871 ++++ b/drivers/video/console/fbcon.c
872 +@@ -80,6 +80,7 @@
873 + #include <asm/system.h>
874 +
875 + #include "fbcon.h"
876 ++#include "fbcondecor.h"
877 +
878 + #ifdef FBCONDEBUG
879 + # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
880 +@@ -95,7 +96,7 @@ enum {
881 +
882 + static struct display fb_display[MAX_NR_CONSOLES];
883 +
884 +-static signed char con2fb_map[MAX_NR_CONSOLES];
885 ++signed char con2fb_map[MAX_NR_CONSOLES];
886 + static signed char con2fb_map_boot[MAX_NR_CONSOLES];
887 +
888 + static int logo_lines;
889 +@@ -287,7 +288,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
890 + !vt_force_oops_output(vc);
891 + }
892 +
893 +-static int get_color(struct vc_data *vc, struct fb_info *info,
894 ++inline int get_color(struct vc_data *vc, struct fb_info *info,
895 + u16 c, int is_fg)
896 + {
897 + int depth = fb_get_color_depth(&info->var, &info->fix);
898 +@@ -528,6 +529,9 @@ static int search_for_mapped_con(void)
899 + static int fbcon_takeover(int show_logo)
900 + {
901 + int err, i;
902 ++#ifdef CONFIG_FB_CON_DECOR
903 ++ struct fb_info *info;
904 ++#endif
905 +
906 + if (!num_registered_fb)
907 + return -ENODEV;
908 +@@ -548,6 +552,12 @@ static int fbcon_takeover(int show_logo)
909 + info_idx = -1;
910 + } else {
911 + fbcon_has_console_bind = 1;
912 ++#ifdef CONFIG_FB_CON_DECOR
913 ++ info = registered_fb[info_idx];
914 ++ unlock_fb_info(info);
915 ++ fbcon_decor_init();
916 ++ lock_fb_info(info);
917 ++#endif
918 + }
919 +
920 + return err;
921 +@@ -1002,6 +1012,12 @@ static const char *fbcon_startup(void)
922 + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
923 + cols /= vc->vc_font.width;
924 + rows /= vc->vc_font.height;
925 ++
926 ++ if (fbcon_decor_active(info, vc)) {
927 ++ cols = vc->vc_decor.twidth / vc->vc_font.width;
928 ++ rows = vc->vc_decor.theight / vc->vc_font.height;
929 ++ }
930 ++
931 + vc_resize(vc, cols, rows);
932 +
933 + DPRINTK("mode: %s\n", info->fix.id);
934 +@@ -1031,7 +1047,7 @@ static void fbcon_init(struct vc_data *vc, int init)
935 + cap = info->flags;
936 +
937 + if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
938 +- (info->fix.type == FB_TYPE_TEXT))
939 ++ (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
940 + logo = 0;
941 +
942 + if (var_to_display(p, &info->var, info))
943 +@@ -1241,6 +1257,11 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
944 + if (sy < vc->vc_top && vc->vc_top == logo_lines)
945 + vc->vc_top = 0;
946 +
947 ++ if (fbcon_decor_active(info, vc)) {
948 ++ fbcon_decor_clear(vc, info, sy, sx, height, width);
949 ++ return;
950 ++ }
951 ++
952 + /* Split blits that cross physical y_wrap boundary */
953 +
954 + y_break = p->vrows - p->yscroll;
955 +@@ -1260,10 +1281,15 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
956 + struct display *p = &fb_display[vc->vc_num];
957 + struct fbcon_ops *ops = info->fbcon_par;
958 +
959 +- if (!fbcon_is_inactive(vc, info))
960 +- ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
961 +- get_color(vc, info, scr_readw(s), 1),
962 +- get_color(vc, info, scr_readw(s), 0));
963 ++ if (!fbcon_is_inactive(vc, info)) {
964 ++
965 ++ if (fbcon_decor_active(info, vc))
966 ++ fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
967 ++ else
968 ++ ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
969 ++ get_color(vc, info, scr_readw(s), 1),
970 ++ get_color(vc, info, scr_readw(s), 0));
971 ++ }
972 + }
973 +
974 + static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
975 +@@ -1279,8 +1305,13 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
976 + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
977 + struct fbcon_ops *ops = info->fbcon_par;
978 +
979 +- if (!fbcon_is_inactive(vc, info))
980 +- ops->clear_margins(vc, info, bottom_only);
981 ++ if (!fbcon_is_inactive(vc, info)) {
982 ++ if (fbcon_decor_active(info, vc)) {
983 ++ fbcon_decor_clear_margins(vc, info, bottom_only);
984 ++ } else {
985 ++ ops->clear_margins(vc, info, bottom_only);
986 ++ }
987 ++ }
988 + }
989 +
990 + static void fbcon_cursor(struct vc_data *vc, int mode)
991 +@@ -1800,7 +1831,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
992 + count = vc->vc_rows;
993 + if (softback_top)
994 + fbcon_softback_note(vc, t, count);
995 +- if (logo_shown >= 0)
996 ++ if (logo_shown >= 0 || fbcon_decor_active(info, vc))
997 + goto redraw_up;
998 + switch (p->scrollmode) {
999 + case SCROLL_MOVE:
1000 +@@ -1893,6 +1924,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
1001 + count = vc->vc_rows;
1002 + if (logo_shown >= 0)
1003 + goto redraw_down;
1004 ++ if (fbcon_decor_active(info, vc))
1005 ++ goto redraw_down;
1006 + switch (p->scrollmode) {
1007 + case SCROLL_MOVE:
1008 + fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
1009 +@@ -2041,6 +2074,13 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
1010 + }
1011 + return;
1012 + }
1013 ++
1014 ++ if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
1015 ++ /* must use slower redraw bmove to keep background pic intact */
1016 ++ fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
1017 ++ return;
1018 ++ }
1019 ++
1020 + ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
1021 + height, width);
1022 + }
1023 +@@ -2111,8 +2151,8 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1024 + var.yres = virt_h * virt_fh;
1025 + x_diff = info->var.xres - var.xres;
1026 + y_diff = info->var.yres - var.yres;
1027 +- if (x_diff < 0 || x_diff > virt_fw ||
1028 +- y_diff < 0 || y_diff > virt_fh) {
1029 ++ if ((x_diff < 0 || x_diff > virt_fw ||
1030 ++ y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
1031 + const struct fb_videomode *mode;
1032 +
1033 + DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
1034 +@@ -2148,6 +2188,21 @@ static int fbcon_switch(struct vc_data *vc)
1035 +
1036 + info = registered_fb[con2fb_map[vc->vc_num]];
1037 + ops = info->fbcon_par;
1038 ++ prev_console = ops->currcon;
1039 ++ if (prev_console != -1)
1040 ++ old_info = registered_fb[con2fb_map[prev_console]];
1041 ++
1042 ++#ifdef CONFIG_FB_CON_DECOR
1043 ++ if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1044 ++ struct vc_data *vc_curr = vc_cons[prev_console].d;
1045 ++ if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
1046 ++ /* Clear the screen to avoid displaying funky colors during
1047 ++ * palette updates. */
1048 ++ memset((u8 *)info->screen_base + info->fix.line_length * info->var.yoffset,
1049 ++ 0, info->var.yres * info->fix.line_length);
1050 ++ }
1051 ++ }
1052 ++#endif
1053 +
1054 + if (softback_top) {
1055 + if (softback_lines)
1056 +@@ -2166,9 +2221,6 @@ static int fbcon_switch(struct vc_data *vc)
1057 + logo_shown = FBCON_LOGO_CANSHOW;
1058 + }
1059 +
1060 +- prev_console = ops->currcon;
1061 +- if (prev_console != -1)
1062 +- old_info = registered_fb[con2fb_map[prev_console]];
1063 + /*
1064 + * FIXME: If we have multiple fbdev's loaded, we need to
1065 + * update all info->currcon. Perhaps, we can place this
1066 +@@ -2212,6 +2264,18 @@ static int fbcon_switch(struct vc_data *vc)
1067 + fbcon_del_cursor_timer(old_info);
1068 + }
1069 +
1070 ++ if (fbcon_decor_active_vc(vc)) {
1071 ++ struct vc_data *vc_curr = vc_cons[prev_console].d;
1072 ++
1073 ++ if (!vc_curr->vc_decor.theme ||
1074 ++ strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
1075 ++ (fbcon_decor_active_nores(info, vc_curr) &&
1076 ++ !fbcon_decor_active(info, vc_curr))) {
1077 ++ if (fbcon_decor_call_helper("modechange", vc->vc_num))
1078 ++ fbcon_decor_disable(vc, 0);
1079 ++ }
1080 ++ }
1081 ++
1082 + if (fbcon_is_inactive(vc, info) ||
1083 + ops->blank_state != FB_BLANK_UNBLANK)
1084 + fbcon_del_cursor_timer(info);
1085 +@@ -2320,15 +2384,20 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
1086 + }
1087 + }
1088 +
1089 +- if (!fbcon_is_inactive(vc, info)) {
1090 ++ if (!fbcon_is_inactive(vc, info)) {
1091 + if (ops->blank_state != blank) {
1092 + ops->blank_state = blank;
1093 + fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
1094 + ops->cursor_flash = (!blank);
1095 +
1096 +- if (!(info->flags & FBINFO_MISC_USEREVENT))
1097 +- if (fb_blank(info, blank))
1098 +- fbcon_generic_blank(vc, info, blank);
1099 ++ if (!(info->flags & FBINFO_MISC_USEREVENT)) {
1100 ++ if (fb_blank(info, blank)) {
1101 ++ if (fbcon_decor_active(info, vc))
1102 ++ fbcon_decor_blank(vc, info, blank);
1103 ++ else
1104 ++ fbcon_generic_blank(vc, info, blank);
1105 ++ }
1106 ++ }
1107 + }
1108 +
1109 + if (!blank)
1110 +@@ -2503,13 +2572,22 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
1111 + }
1112 +
1113 + if (resize) {
1114 ++ /* reset wrap/pan */
1115 + int cols, rows;
1116 +
1117 + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
1118 + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1119 ++
1120 ++ if (fbcon_decor_active(info, vc)) {
1121 ++ info->var.xoffset = info->var.yoffset = p->yscroll = 0;
1122 ++ cols = vc->vc_decor.twidth;
1123 ++ rows = vc->vc_decor.theight;
1124 ++ }
1125 + cols /= w;
1126 + rows /= h;
1127 ++
1128 + vc_resize(vc, cols, rows);
1129 ++
1130 + if (CON_IS_VISIBLE(vc) && softback_buf)
1131 + fbcon_update_softback(vc);
1132 + } else if (CON_IS_VISIBLE(vc)
1133 +@@ -2638,7 +2716,11 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
1134 + int i, j, k, depth;
1135 + u8 val;
1136 +
1137 +- if (fbcon_is_inactive(vc, info))
1138 ++ if (fbcon_is_inactive(vc, info)
1139 ++#ifdef CONFIG_FB_CON_DECOR
1140 ++ || vc->vc_num != fg_console
1141 ++#endif
1142 ++ )
1143 + return -EINVAL;
1144 +
1145 + if (!CON_IS_VISIBLE(vc))
1146 +@@ -2664,7 +2746,49 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
1147 + } else
1148 + fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
1149 +
1150 +- return fb_set_cmap(&palette_cmap, info);
1151 ++ if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
1152 ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1153 ++
1154 ++ u16 *red, *green, *blue;
1155 ++ int minlen = min(min(info->var.red.length, info->var.green.length),
1156 ++ info->var.blue.length);
1157 ++ int h;
1158 ++
1159 ++ struct fb_cmap cmap = {
1160 ++ .start = 0,
1161 ++ .len = (1 << minlen),
1162 ++ .red = NULL,
1163 ++ .green = NULL,
1164 ++ .blue = NULL,
1165 ++ .transp = NULL
1166 ++ };
1167 ++
1168 ++ red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
1169 ++
1170 ++ if (!red)
1171 ++ goto out;
1172 ++
1173 ++ green = red + 256;
1174 ++ blue = green + 256;
1175 ++ cmap.red = red;
1176 ++ cmap.green = green;
1177 ++ cmap.blue = blue;
1178 ++
1179 ++ for (i = 0; i < cmap.len; i++) {
1180 ++ red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
1181 ++ }
1182 ++
1183 ++ h = fb_set_cmap(&cmap, info);
1184 ++ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
1185 ++ kfree(red);
1186 ++
1187 ++ return h;
1188 ++
1189 ++ } else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
1190 ++ info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
1191 ++ fb_set_cmap(&info->bgdecor.cmap, info);
1192 ++
1193 ++out: return fb_set_cmap(&palette_cmap, info);
1194 + }
1195 +
1196 + static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
1197 +@@ -2872,7 +2996,7 @@ static void fbcon_modechanged(struct fb_info *info)
1198 + struct fbcon_ops *ops = info->fbcon_par;
1199 + struct vc_data *vc;
1200 + struct display *p;
1201 +- int rows, cols;
1202 ++ int rows, cols, res;
1203 +
1204 + if (!ops || ops->currcon < 0)
1205 + return;
1206 +@@ -2890,7 +3014,18 @@ static void fbcon_modechanged(struct fb_info *info)
1207 + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1208 + cols /= vc->vc_font.width;
1209 + rows /= vc->vc_font.height;
1210 +- vc_resize(vc, cols, rows);
1211 ++
1212 ++ if (!fbcon_decor_active_nores(info, vc)) {
1213 ++ vc_resize(vc, cols, rows);
1214 ++ } else {
1215 ++ /* HACK: Do this properly at some point.. */
1216 ++ unlock_fb_info(info);
1217 ++ res = fbcon_decor_call_helper("modechange", vc->vc_num);
1218 ++ lock_fb_info(info);
1219 ++ if (res)
1220 ++ fbcon_decor_disable(vc, 0);
1221 ++ }
1222 ++
1223 + updatescrollmode(p, info, vc);
1224 + scrollback_max = 0;
1225 + scrollback_current = 0;
1226 +@@ -3321,7 +3456,7 @@ static ssize_t store_rotate(struct device *device,
1227 + if (fbcon_has_exited)
1228 + return count;
1229 +
1230 +- console_lock();
1231 ++ console_unlock();
1232 + idx = con2fb_map[fg_console];
1233 +
1234 + if (idx == -1 || registered_fb[idx] == NULL)
1235 +@@ -3369,7 +3504,7 @@ static ssize_t show_rotate(struct device *device,
1236 + if (fbcon_has_exited)
1237 + return 0;
1238 +
1239 +- console_lock();
1240 ++ console_unlock();
1241 + idx = con2fb_map[fg_console];
1242 +
1243 + if (idx == -1 || registered_fb[idx] == NULL)
1244 +@@ -3545,6 +3680,7 @@ static void fbcon_exit(void)
1245 + }
1246 + }
1247 +
1248 ++ fbcon_decor_exit();
1249 + fbcon_has_exited = 1;
1250 + }
1251 +
1252 +diff --git a/drivers/video/console/fbcondecor.c b/drivers/video/console/fbcondecor.c
1253 +new file mode 100644
1254 +index 0000000..43e8063
1255 +--- /dev/null
1256 ++++ b/drivers/video/console/fbcondecor.c
1257 +@@ -0,0 +1,562 @@
1258 ++/*
1259 ++ * linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations
1260 ++ *
1261 ++ * Copyright (C) 2004-2009 Michal Januszewski <spock@g.o>
1262 ++ *
1263 ++ * Code based upon "Bootsplash" (C) 2001-2003
1264 ++ * Volker Poplawski <volker@×××××××××.de>,
1265 ++ * Stefan Reinauer <stepan@××××.de>,
1266 ++ * Steffen Winterfeldt <snwint@××××.de>,
1267 ++ * Michael Schroeder <mls@××××.de>,
1268 ++ * Ken Wimer <wimer@××××.de>.
1269 ++ *
1270 ++ * Compat ioctl support by Thorsten Klein <TK@××××××××××××××.de>.
1271 ++ *
1272 ++ * This file is subject to the terms and conditions of the GNU General Public
1273 ++ * License. See the file COPYING in the main directory of this archive for
1274 ++ * more details.
1275 ++ *
1276 ++ */
1277 ++#include <linux/module.h>
1278 ++#include <linux/kernel.h>
1279 ++#include <linux/string.h>
1280 ++#include <linux/types.h>
1281 ++#include <linux/fb.h>
1282 ++#include <linux/vt_kern.h>
1283 ++#include <linux/vmalloc.h>
1284 ++#include <linux/unistd.h>
1285 ++#include <linux/syscalls.h>
1286 ++#include <linux/init.h>
1287 ++#include <linux/proc_fs.h>
1288 ++#include <linux/workqueue.h>
1289 ++#include <linux/kmod.h>
1290 ++#include <linux/miscdevice.h>
1291 ++#include <linux/device.h>
1292 ++#include <linux/fs.h>
1293 ++#include <linux/compat.h>
1294 ++#include <linux/console.h>
1295 ++
1296 ++#include <asm/uaccess.h>
1297 ++#include <asm/irq.h>
1298 ++#include <asm/system.h>
1299 ++
1300 ++#include "fbcon.h"
1301 ++#include "fbcondecor.h"
1302 ++
1303 ++extern signed char con2fb_map[];
1304 ++static int fbcon_decor_enable(struct vc_data *vc);
1305 ++char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
1306 ++static int initialized = 0;
1307 ++
1308 ++int fbcon_decor_call_helper(char* cmd, unsigned short vc)
1309 ++{
1310 ++ char *envp[] = {
1311 ++ "HOME=/",
1312 ++ "PATH=/sbin:/bin",
1313 ++ NULL
1314 ++ };
1315 ++
1316 ++ char tfb[5];
1317 ++ char tcons[5];
1318 ++ unsigned char fb = (int) con2fb_map[vc];
1319 ++
1320 ++ char *argv[] = {
1321 ++ fbcon_decor_path,
1322 ++ "2",
1323 ++ cmd,
1324 ++ tcons,
1325 ++ tfb,
1326 ++ vc_cons[vc].d->vc_decor.theme,
1327 ++ NULL
1328 ++ };
1329 ++
1330 ++ snprintf(tfb,5,"%d",fb);
1331 ++ snprintf(tcons,5,"%d",vc);
1332 ++
1333 ++ return call_usermodehelper(fbcon_decor_path, argv, envp, 1);
1334 ++}
1335 ++
1336 ++/* Disables fbcondecor on a virtual console; called with console sem held. */
1337 ++int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw)
1338 ++{
1339 ++ struct fb_info* info;
1340 ++
1341 ++ if (!vc->vc_decor.state)
1342 ++ return -EINVAL;
1343 ++
1344 ++ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1345 ++
1346 ++ if (info == NULL)
1347 ++ return -EINVAL;
1348 ++
1349 ++ vc->vc_decor.state = 0;
1350 ++ vc_resize(vc, info->var.xres / vc->vc_font.width,
1351 ++ info->var.yres / vc->vc_font.height);
1352 ++
1353 ++ if (fg_console == vc->vc_num && redraw) {
1354 ++ redraw_screen(vc, 0);
1355 ++ update_region(vc, vc->vc_origin +
1356 ++ vc->vc_size_row * vc->vc_top,
1357 ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1358 ++ }
1359 ++
1360 ++ printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n",
1361 ++ vc->vc_num);
1362 ++
1363 ++ return 0;
1364 ++}
1365 ++
1366 ++/* Enables fbcondecor on a virtual console; called with console sem held. */
1367 ++static int fbcon_decor_enable(struct vc_data *vc)
1368 ++{
1369 ++ struct fb_info* info;
1370 ++
1371 ++ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1372 ++
1373 ++ if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 ||
1374 ++ info == NULL || vc->vc_decor.state || (!info->bgdecor.data &&
1375 ++ vc->vc_num == fg_console))
1376 ++ return -EINVAL;
1377 ++
1378 ++ vc->vc_decor.state = 1;
1379 ++ vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width,
1380 ++ vc->vc_decor.theight / vc->vc_font.height);
1381 ++
1382 ++ if (fg_console == vc->vc_num) {
1383 ++ redraw_screen(vc, 0);
1384 ++ update_region(vc, vc->vc_origin +
1385 ++ vc->vc_size_row * vc->vc_top,
1386 ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1387 ++ fbcon_decor_clear_margins(vc, info, 0);
1388 ++ }
1389 ++
1390 ++ printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n",
1391 ++ vc->vc_num);
1392 ++
1393 ++ return 0;
1394 ++}
1395 ++
1396 ++static inline long fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin)
1397 ++{
1398 ++ int ret;
1399 ++
1400 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1401 ++ console_lock();
1402 ++ if (!state)
1403 ++ ret = fbcon_decor_disable(vc, 1);
1404 ++ else
1405 ++ ret = fbcon_decor_enable(vc);
1406 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1407 ++ console_unlock();
1408 ++
1409 ++ return ret;
1410 ++}
1411 ++
1412 ++static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state)
1413 ++{
1414 ++ *state = vc->vc_decor.state;
1415 ++}
1416 ++
1417 ++static long fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin)
1418 ++{
1419 ++ struct fb_info *info;
1420 ++ int len;
1421 ++ char *tmp;
1422 ++
1423 ++ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1424 ++
1425 ++ if (info == NULL || !cfg->twidth || !cfg->theight ||
1426 ++ cfg->tx + cfg->twidth > info->var.xres ||
1427 ++ cfg->ty + cfg->theight > info->var.yres)
1428 ++ return -EINVAL;
1429 ++
1430 ++ len = strlen_user(cfg->theme);
1431 ++ if (!len || len > FBCON_DECOR_THEME_LEN)
1432 ++ return -EINVAL;
1433 ++ tmp = kmalloc(len, GFP_KERNEL);
1434 ++ if (!tmp)
1435 ++ return -ENOMEM;
1436 ++ if (copy_from_user(tmp, (void __user *)cfg->theme, len))
1437 ++ return -EFAULT;
1438 ++ cfg->theme = tmp;
1439 ++ cfg->state = 0;
1440 ++
1441 ++ /* If this ioctl is a response to a request from kernel, the console sem
1442 ++ * is already held; we also don't need to disable decor because either the
1443 ++ * new config and background picture will be successfully loaded, and the
1444 ++ * decor will stay on, or in case of a failure it'll be turned off in fbcon. */
1445 ++ if (origin == FBCON_DECOR_IO_ORIG_USER) {
1446 ++ console_lock();
1447 ++ if (vc->vc_decor.state)
1448 ++ fbcon_decor_disable(vc, 1);
1449 ++ }
1450 ++
1451 ++ if (vc->vc_decor.theme)
1452 ++ kfree(vc->vc_decor.theme);
1453 ++
1454 ++ vc->vc_decor = *cfg;
1455 ++
1456 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1457 ++ console_unlock();
1458 ++
1459 ++ printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n",
1460 ++ vc->vc_num, vc->vc_decor.theme);
1461 ++ return 0;
1462 ++}
1463 ++
1464 ++static long fbcon_decor_ioctl_dogetcfg(struct vc_data *vc, struct vc_decor *decor)
1465 ++{
1466 ++ char __user *tmp;
1467 ++
1468 ++ tmp = decor->theme;
1469 ++ *decor = vc->vc_decor;
1470 ++ decor->theme = tmp;
1471 ++
1472 ++ if (vc->vc_decor.theme) {
1473 ++ if (copy_to_user(tmp, vc->vc_decor.theme, strlen(vc->vc_decor.theme) + 1))
1474 ++ return -EFAULT;
1475 ++ } else
1476 ++ if (put_user(0, tmp))
1477 ++ return -EFAULT;
1478 ++
1479 ++ return 0;
1480 ++}
1481 ++
1482 ++static long fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img, unsigned char origin)
1483 ++{
1484 ++ struct fb_info *info;
1485 ++ int len;
1486 ++ u8 *tmp;
1487 ++
1488 ++ if (vc->vc_num != fg_console)
1489 ++ return -EINVAL;
1490 ++
1491 ++ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1492 ++
1493 ++ if (info == NULL)
1494 ++ return -EINVAL;
1495 ++
1496 ++ if (img->width != info->var.xres || img->height != info->var.yres) {
1497 ++ printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n");
1498 ++ printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height, info->var.xres, info->var.yres);
1499 ++ return -EINVAL;
1500 ++ }
1501 ++
1502 ++ if (img->depth != info->var.bits_per_pixel) {
1503 ++ printk(KERN_ERR "fbcondecor: picture depth mismatch\n");
1504 ++ return -EINVAL;
1505 ++ }
1506 ++
1507 ++ if (img->depth == 8) {
1508 ++ if (!img->cmap.len || !img->cmap.red || !img->cmap.green ||
1509 ++ !img->cmap.blue)
1510 ++ return -EINVAL;
1511 ++
1512 ++ tmp = vmalloc(img->cmap.len * 3 * 2);
1513 ++ if (!tmp)
1514 ++ return -ENOMEM;
1515 ++
1516 ++ if (copy_from_user(tmp,
1517 ++ (void __user*)img->cmap.red, (img->cmap.len << 1)) ||
1518 ++ copy_from_user(tmp + (img->cmap.len << 1),
1519 ++ (void __user*)img->cmap.green, (img->cmap.len << 1)) ||
1520 ++ copy_from_user(tmp + (img->cmap.len << 2),
1521 ++ (void __user*)img->cmap.blue, (img->cmap.len << 1))) {
1522 ++ vfree(tmp);
1523 ++ return -EFAULT;
1524 ++ }
1525 ++
1526 ++ img->cmap.transp = NULL;
1527 ++ img->cmap.red = (u16*)tmp;
1528 ++ img->cmap.green = img->cmap.red + img->cmap.len;
1529 ++ img->cmap.blue = img->cmap.green + img->cmap.len;
1530 ++ } else {
1531 ++ img->cmap.red = NULL;
1532 ++ }
1533 ++
1534 ++ len = ((img->depth + 7) >> 3) * img->width * img->height;
1535 ++
1536 ++ /*
1537 ++ * Allocate an additional byte so that we never go outside of the
1538 ++ * buffer boundaries in the rendering functions in a 24 bpp mode.
1539 ++ */
1540 ++ tmp = vmalloc(len + 1);
1541 ++
1542 ++ if (!tmp)
1543 ++ goto out;
1544 ++
1545 ++ if (copy_from_user(tmp, (void __user*)img->data, len))
1546 ++ goto out;
1547 ++
1548 ++ img->data = tmp;
1549 ++
1550 ++ /* If this ioctl is a response to a request from kernel, the console sem
1551 ++ * is already held. */
1552 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1553 ++ console_lock();
1554 ++
1555 ++ if (info->bgdecor.data)
1556 ++ vfree((u8*)info->bgdecor.data);
1557 ++ if (info->bgdecor.cmap.red)
1558 ++ vfree(info->bgdecor.cmap.red);
1559 ++
1560 ++ info->bgdecor = *img;
1561 ++
1562 ++ if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) {
1563 ++ redraw_screen(vc, 0);
1564 ++ update_region(vc, vc->vc_origin +
1565 ++ vc->vc_size_row * vc->vc_top,
1566 ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1567 ++ fbcon_decor_clear_margins(vc, info, 0);
1568 ++ }
1569 ++
1570 ++ if (origin == FBCON_DECOR_IO_ORIG_USER)
1571 ++ console_unlock();
1572 ++
1573 ++ return 0;
1574 ++
1575 ++out: if (img->cmap.red)
1576 ++ vfree(img->cmap.red);
1577 ++
1578 ++ if (tmp)
1579 ++ vfree(tmp);
1580 ++ return -ENOMEM;
1581 ++}
1582 ++
1583 ++static long fbcon_decor_ioctl(struct file *filp, u_int cmd,
1584 ++ u_long arg)
1585 ++{
1586 ++ struct fbcon_decor_iowrapper __user *wrapper = (void __user*) arg;
1587 ++ struct vc_data *vc = NULL;
1588 ++ unsigned short vc_num = 0;
1589 ++ unsigned char origin = 0;
1590 ++ void __user *data = NULL;
1591 ++
1592 ++ if (!access_ok(VERIFY_READ, wrapper,
1593 ++ sizeof(struct fbcon_decor_iowrapper)))
1594 ++ return -EFAULT;
1595 ++
1596 ++ __get_user(vc_num, &wrapper->vc);
1597 ++ __get_user(origin, &wrapper->origin);
1598 ++ __get_user(data, &wrapper->data);
1599 ++
1600 ++ if (!vc_cons_allocated(vc_num))
1601 ++ return -EINVAL;
1602 ++
1603 ++ vc = vc_cons[vc_num].d;
1604 ++
1605 ++ switch (cmd) {
1606 ++ case FBIOCONDECOR_SETPIC:
1607 ++ {
1608 ++ struct fb_image img;
1609 ++ if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image)))
1610 ++ return -EFAULT;
1611 ++
1612 ++ return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
1613 ++ }
1614 ++ case FBIOCONDECOR_SETCFG:
1615 ++ {
1616 ++ struct vc_decor cfg;
1617 ++ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
1618 ++ return -EFAULT;
1619 ++
1620 ++ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
1621 ++ }
1622 ++ case FBIOCONDECOR_GETCFG:
1623 ++ {
1624 ++ int rval;
1625 ++ struct vc_decor cfg;
1626 ++
1627 ++ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
1628 ++ return -EFAULT;
1629 ++
1630 ++ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
1631 ++
1632 ++ if (copy_to_user(data, &cfg, sizeof(struct vc_decor)))
1633 ++ return -EFAULT;
1634 ++ return rval;
1635 ++ }
1636 ++ case FBIOCONDECOR_SETSTATE:
1637 ++ {
1638 ++ unsigned int state = 0;
1639 ++ if (get_user(state, (unsigned int __user *)data))
1640 ++ return -EFAULT;
1641 ++ return fbcon_decor_ioctl_dosetstate(vc, state, origin);
1642 ++ }
1643 ++ case FBIOCONDECOR_GETSTATE:
1644 ++ {
1645 ++ unsigned int state = 0;
1646 ++ fbcon_decor_ioctl_dogetstate(vc, &state);
1647 ++ return put_user(state, (unsigned int __user *)data);
1648 ++ }
1649 ++
1650 ++ default:
1651 ++ return -ENOIOCTLCMD;
1652 ++ }
1653 ++}
1654 ++
1655 ++#ifdef CONFIG_COMPAT
1656 ++
1657 ++static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
1658 ++
1659 ++ struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg;
1660 ++ struct vc_data *vc = NULL;
1661 ++ unsigned short vc_num = 0;
1662 ++ unsigned char origin = 0;
1663 ++ compat_uptr_t data_compat = 0;
1664 ++ void __user *data = NULL;
1665 ++
1666 ++ if (!access_ok(VERIFY_READ, wrapper,
1667 ++ sizeof(struct fbcon_decor_iowrapper32)))
1668 ++ return -EFAULT;
1669 ++
1670 ++ __get_user(vc_num, &wrapper->vc);
1671 ++ __get_user(origin, &wrapper->origin);
1672 ++ __get_user(data_compat, &wrapper->data);
1673 ++ data = compat_ptr(data_compat);
1674 ++
1675 ++ if (!vc_cons_allocated(vc_num))
1676 ++ return -EINVAL;
1677 ++
1678 ++ vc = vc_cons[vc_num].d;
1679 ++
1680 ++ switch (cmd) {
1681 ++ case FBIOCONDECOR_SETPIC32:
1682 ++ {
1683 ++ struct fb_image32 img_compat;
1684 ++ struct fb_image img;
1685 ++
1686 ++ if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32)))
1687 ++ return -EFAULT;
1688 ++
1689 ++ fb_image_from_compat(img, img_compat);
1690 ++
1691 ++ return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
1692 ++ }
1693 ++
1694 ++ case FBIOCONDECOR_SETCFG32:
1695 ++ {
1696 ++ struct vc_decor32 cfg_compat;
1697 ++ struct vc_decor cfg;
1698 ++
1699 ++ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
1700 ++ return -EFAULT;
1701 ++
1702 ++ vc_decor_from_compat(cfg, cfg_compat);
1703 ++
1704 ++ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
1705 ++ }
1706 ++
1707 ++ case FBIOCONDECOR_GETCFG32:
1708 ++ {
1709 ++ int rval;
1710 ++ struct vc_decor32 cfg_compat;
1711 ++ struct vc_decor cfg;
1712 ++
1713 ++ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
1714 ++ return -EFAULT;
1715 ++ cfg.theme = compat_ptr(cfg_compat.theme);
1716 ++
1717 ++ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
1718 ++
1719 ++ vc_decor_to_compat(cfg_compat, cfg);
1720 ++
1721 ++ if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32)))
1722 ++ return -EFAULT;
1723 ++ return rval;
1724 ++ }
1725 ++
1726 ++ case FBIOCONDECOR_SETSTATE32:
1727 ++ {
1728 ++ compat_uint_t state_compat = 0;
1729 ++ unsigned int state = 0;
1730 ++
1731 ++ if (get_user(state_compat, (compat_uint_t __user *)data))
1732 ++ return -EFAULT;
1733 ++
1734 ++ state = (unsigned int)state_compat;
1735 ++
1736 ++ return fbcon_decor_ioctl_dosetstate(vc, state, origin);
1737 ++ }
1738 ++
1739 ++ case FBIOCONDECOR_GETSTATE32:
1740 ++ {
1741 ++ compat_uint_t state_compat = 0;
1742 ++ unsigned int state = 0;
1743 ++
1744 ++ fbcon_decor_ioctl_dogetstate(vc, &state);
1745 ++ state_compat = (compat_uint_t)state;
1746 ++
1747 ++ return put_user(state_compat, (compat_uint_t __user *)data);
1748 ++ }
1749 ++
1750 ++ default:
1751 ++ return -ENOIOCTLCMD;
1752 ++ }
1753 ++}
1754 ++#else
1755 ++ #define fbcon_decor_compat_ioctl NULL
1756 ++#endif
1757 ++
1758 ++static struct file_operations fbcon_decor_ops = {
1759 ++ .owner = THIS_MODULE,
1760 ++ .unlocked_ioctl = fbcon_decor_ioctl,
1761 ++ .compat_ioctl = fbcon_decor_compat_ioctl
1762 ++};
1763 ++
1764 ++static struct miscdevice fbcon_decor_dev = {
1765 ++ .minor = MISC_DYNAMIC_MINOR,
1766 ++ .name = "fbcondecor",
1767 ++ .fops = &fbcon_decor_ops
1768 ++};
1769 ++
1770 ++void fbcon_decor_reset(void)
1771 ++{
1772 ++ struct fb_info *info;
1773 ++ struct vc_data *vc;
1774 ++ int i;
1775 ++
1776 ++ vc = vc_cons[0].d;
1777 ++ info = registered_fb[0];
1778 ++
1779 ++ for (i = 0; i < num_registered_fb; i++) {
1780 ++ registered_fb[i]->bgdecor.data = NULL;
1781 ++ registered_fb[i]->bgdecor.cmap.red = NULL;
1782 ++ }
1783 ++
1784 ++ for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
1785 ++ vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth =
1786 ++ vc_cons[i].d->vc_decor.theight = 0;
1787 ++ vc_cons[i].d->vc_decor.theme = NULL;
1788 ++ }
1789 ++
1790 ++ return;
1791 ++}
1792 ++
1793 ++int fbcon_decor_init(void)
1794 ++{
1795 ++ int i;
1796 ++
1797 ++ fbcon_decor_reset();
1798 ++
1799 ++ if (initialized)
1800 ++ return 0;
1801 ++
1802 ++ i = misc_register(&fbcon_decor_dev);
1803 ++ if (i) {
1804 ++ printk(KERN_ERR "fbcondecor: failed to register device\n");
1805 ++ return i;
1806 ++ }
1807 ++
1808 ++ fbcon_decor_call_helper("init", 0);
1809 ++ initialized = 1;
1810 ++ return 0;
1811 ++}
1812 ++
1813 ++int fbcon_decor_exit(void)
1814 ++{
1815 ++ fbcon_decor_reset();
1816 ++ return 0;
1817 ++}
1818 ++
1819 ++EXPORT_SYMBOL(fbcon_decor_path);
1820 +diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h
1821 +new file mode 100644
1822 +index 0000000..1bcd6f6
1823 +--- /dev/null
1824 ++++ b/drivers/video/console/fbcondecor.h
1825 +@@ -0,0 +1,78 @@
1826 ++/*
1827 ++ * linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers
1828 ++ *
1829 ++ * Copyright (C) 2004 Michal Januszewski <spock@g.o>
1830 ++ *
1831 ++ */
1832 ++
1833 ++#ifndef __FBCON_DECOR_H
1834 ++#define __FBCON_DECOR_H
1835 ++
1836 ++#ifndef _LINUX_FB_H
1837 ++#include <linux/fb.h>
1838 ++#endif
1839 ++
1840 ++/* This is needed for vc_cons in fbcmap.c */
1841 ++#include <linux/vt_kern.h>
1842 ++
1843 ++struct fb_cursor;
1844 ++struct fb_info;
1845 ++struct vc_data;
1846 ++
1847 ++#ifdef CONFIG_FB_CON_DECOR
1848 ++/* fbcondecor.c */
1849 ++int fbcon_decor_init(void);
1850 ++int fbcon_decor_exit(void);
1851 ++int fbcon_decor_call_helper(char* cmd, unsigned short cons);
1852 ++int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw);
1853 ++
1854 ++/* cfbcondecor.c */
1855 ++void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
1856 ++void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor);
1857 ++void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
1858 ++void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
1859 ++void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank);
1860 ++void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
1861 ++void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
1862 ++void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
1863 ++
1864 ++/* vt.c */
1865 ++void acquire_console_sem(void);
1866 ++void release_console_sem(void);
1867 ++void do_unblank_screen(int entering_gfx);
1868 ++
1869 ++/* struct vc_data *y */
1870 ++#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme)
1871 ++
1872 ++/* struct fb_info *x, struct vc_data *y */
1873 ++#define fbcon_decor_active_nores(x,y) (x->bgdecor.data && fbcon_decor_active_vc(y))
1874 ++
1875 ++/* struct fb_info *x, struct vc_data *y */
1876 ++#define fbcon_decor_active(x,y) (fbcon_decor_active_nores(x,y) && \
1877 ++ x->bgdecor.width == x->var.xres && \
1878 ++ x->bgdecor.height == x->var.yres && \
1879 ++ x->bgdecor.depth == x->var.bits_per_pixel)
1880 ++
1881 ++
1882 ++#else /* CONFIG_FB_CON_DECOR */
1883 ++
1884 ++static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
1885 ++static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
1886 ++static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
1887 ++static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
1888 ++static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
1889 ++static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
1890 ++static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
1891 ++static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
1892 ++static inline int fbcon_decor_call_helper(char* cmd, unsigned short cons) { return 0; }
1893 ++static inline int fbcon_decor_init(void) { return 0; }
1894 ++static inline int fbcon_decor_exit(void) { return 0; }
1895 ++static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
1896 ++
1897 ++#define fbcon_decor_active_vc(y) (0)
1898 ++#define fbcon_decor_active_nores(x,y) (0)
1899 ++#define fbcon_decor_active(x,y) (0)
1900 ++
1901 ++#endif /* CONFIG_FB_CON_DECOR */
1902 ++
1903 ++#endif /* __FBCON_DECOR_H */
1904 +diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
1905 +index 5c3960d..529db5b 100644
1906 +--- a/drivers/video/fbcmap.c
1907 ++++ b/drivers/video/fbcmap.c
1908 +@@ -17,6 +17,8 @@
1909 + #include <linux/slab.h>
1910 + #include <linux/uaccess.h>
1911 +
1912 ++#include "console/fbcondecor.h"
1913 ++
1914 + static u16 red2[] __read_mostly = {
1915 + 0x0000, 0xaaaa
1916 + };
1917 +@@ -254,9 +256,12 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
1918 + break;
1919 + }
1920 + }
1921 +- if (rc == 0)
1922 ++ if (rc == 0) {
1923 + fb_copy_cmap(cmap, &info->cmap);
1924 +-
1925 ++ if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
1926 ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR)
1927 ++ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
1928 ++ }
1929 + return rc;
1930 + }
1931 +
1932 +diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
1933 +index e2bf953..cf0ecf7 100644
1934 +--- a/drivers/video/fbmem.c
1935 ++++ b/drivers/video/fbmem.c
1936 +@@ -1166,15 +1166,6 @@ struct fb_fix_screeninfo32 {
1937 + u16 reserved[3];
1938 + };
1939 +
1940 +-struct fb_cmap32 {
1941 +- u32 start;
1942 +- u32 len;
1943 +- compat_caddr_t red;
1944 +- compat_caddr_t green;
1945 +- compat_caddr_t blue;
1946 +- compat_caddr_t transp;
1947 +-};
1948 +-
1949 + static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1950 + unsigned long arg)
1951 + {
1952 +diff --git a/include/linux/console_decor.h b/include/linux/console_decor.h
1953 +new file mode 100644
1954 +index 0000000..04b8d80
1955 +--- /dev/null
1956 ++++ b/include/linux/console_decor.h
1957 +@@ -0,0 +1,46 @@
1958 ++#ifndef _LINUX_CONSOLE_DECOR_H_
1959 ++#define _LINUX_CONSOLE_DECOR_H_ 1
1960 ++
1961 ++/* A structure used by the framebuffer console decorations (drivers/video/console/fbcondecor.c) */
1962 ++struct vc_decor {
1963 ++ __u8 bg_color; /* The color that is to be treated as transparent */
1964 ++ __u8 state; /* Current decor state: 0 = off, 1 = on */
1965 ++ __u16 tx, ty; /* Top left corner coordinates of the text field */
1966 ++ __u16 twidth, theight; /* Width and height of the text field */
1967 ++ char* theme;
1968 ++};
1969 ++
1970 ++#ifdef __KERNEL__
1971 ++#ifdef CONFIG_COMPAT
1972 ++#include <linux/compat.h>
1973 ++
1974 ++struct vc_decor32 {
1975 ++ __u8 bg_color; /* The color that is to be treated as transparent */
1976 ++ __u8 state; /* Current decor state: 0 = off, 1 = on */
1977 ++ __u16 tx, ty; /* Top left corner coordinates of the text field */
1978 ++ __u16 twidth, theight; /* Width and height of the text field */
1979 ++ compat_uptr_t theme;
1980 ++};
1981 ++
1982 ++#define vc_decor_from_compat(to, from) \
1983 ++ (to).bg_color = (from).bg_color; \
1984 ++ (to).state = (from).state; \
1985 ++ (to).tx = (from).tx; \
1986 ++ (to).ty = (from).ty; \
1987 ++ (to).twidth = (from).twidth; \
1988 ++ (to).theight = (from).theight; \
1989 ++ (to).theme = compat_ptr((from).theme)
1990 ++
1991 ++#define vc_decor_to_compat(to, from) \
1992 ++ (to).bg_color = (from).bg_color; \
1993 ++ (to).state = (from).state; \
1994 ++ (to).tx = (from).tx; \
1995 ++ (to).ty = (from).ty; \
1996 ++ (to).twidth = (from).twidth; \
1997 ++ (to).theight = (from).theight; \
1998 ++ (to).theme = ptr_to_compat((from).theme)
1999 ++
2000 ++#endif /* CONFIG_COMPAT */
2001 ++#endif /* __KERNEL__ */
2002 ++
2003 ++#endif
2004 +diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
2005 +index 7f0c329..98f5d60 100644
2006 +--- a/include/linux/console_struct.h
2007 ++++ b/include/linux/console_struct.h
2008 +@@ -19,6 +19,7 @@
2009 + struct vt_struct;
2010 +
2011 + #define NPAR 16
2012 ++#include <linux/console_decor.h>
2013 +
2014 + struct vc_data {
2015 + struct tty_port port; /* Upper level data */
2016 +@@ -107,6 +108,8 @@ struct vc_data {
2017 + unsigned long vc_uni_pagedir;
2018 + unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
2019 + bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
2020 ++
2021 ++ struct vc_decor vc_decor;
2022 + /* additional information is in vt_kern.h */
2023 + };
2024 +
2025 +diff --git a/include/linux/fb.h b/include/linux/fb.h
2026 +index 68ba85a..da863a2 100644
2027 +--- a/include/linux/fb.h
2028 ++++ b/include/linux/fb.h
2029 +@@ -11,6 +11,23 @@
2030 +
2031 + #define FB_MAX 32 /* sufficient for now */
2032 +
2033 ++struct fbcon_decor_iowrapper {
2034 ++ unsigned short vc; /* Virtual console */
2035 ++ unsigned char origin; /* Point of origin of the request */
2036 ++ void *data;
2037 ++};
2038 ++
2039 ++#ifdef __KERNEL__
2040 ++#ifdef CONFIG_COMPAT
2041 ++#include <linux/compat.h>
2042 ++struct fbcon_decor_iowrapper32 {
2043 ++ unsigned short vc; /* Virtual console */
2044 ++ unsigned char origin; /* Point of origin of the request */
2045 ++ compat_uptr_t data;
2046 ++};
2047 ++#endif /* CONFIG_COMPAT */
2048 ++#endif /* __KERNEL__ */
2049 ++
2050 + /* ioctls
2051 + 0x46 is 'F' */
2052 + #define FBIOGET_VSCREENINFO 0x4600
2053 +@@ -39,6 +56,24 @@
2054 + #define FBIOPUT_MODEINFO 0x4617
2055 + #define FBIOGET_DISPINFO 0x4618
2056 + #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
2057 ++#define FBIOCONDECOR_SETCFG _IOWR('F', 0x19, struct fbcon_decor_iowrapper)
2058 ++#define FBIOCONDECOR_GETCFG _IOR('F', 0x1A, struct fbcon_decor_iowrapper)
2059 ++#define FBIOCONDECOR_SETSTATE _IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
2060 ++#define FBIOCONDECOR_GETSTATE _IOR('F', 0x1C, struct fbcon_decor_iowrapper)
2061 ++#define FBIOCONDECOR_SETPIC _IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
2062 ++#ifdef __KERNEL__
2063 ++#ifdef CONFIG_COMPAT
2064 ++#define FBIOCONDECOR_SETCFG32 _IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
2065 ++#define FBIOCONDECOR_GETCFG32 _IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
2066 ++#define FBIOCONDECOR_SETSTATE32 _IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
2067 ++#define FBIOCONDECOR_GETSTATE32 _IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
2068 ++#define FBIOCONDECOR_SETPIC32 _IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
2069 ++#endif /* CONFIG_COMPAT */
2070 ++#endif /* __KERNEL__ */
2071 ++
2072 ++#define FBCON_DECOR_THEME_LEN 128 /* Lenght of a theme name */
2073 ++#define FBCON_DECOR_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */
2074 ++#define FBCON_DECOR_IO_ORIG_USER 1 /* User ioctl origin */
2075 +
2076 + #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
2077 + #define FB_TYPE_PLANES 1 /* Non interleaved planes */
2078 +@@ -283,6 +318,28 @@ struct fb_cmap {
2079 + __u16 *transp; /* transparency, can be NULL */
2080 + };
2081 +
2082 ++#ifdef __KERNEL__
2083 ++#ifdef CONFIG_COMPAT
2084 ++struct fb_cmap32 {
2085 ++ __u32 start;
2086 ++ __u32 len; /* Number of entries */
2087 ++ compat_uptr_t red; /* Red values */
2088 ++ compat_uptr_t green;
2089 ++ compat_uptr_t blue;
2090 ++ compat_uptr_t transp; /* transparency, can be NULL */
2091 ++};
2092 ++
2093 ++#define fb_cmap_from_compat(to, from) \
2094 ++ (to).start = (from).start; \
2095 ++ (to).len = (from).len; \
2096 ++ (to).red = compat_ptr((from).red); \
2097 ++ (to).green = compat_ptr((from).green); \
2098 ++ (to).blue = compat_ptr((from).blue); \
2099 ++ (to).transp = compat_ptr((from).transp)
2100 ++
2101 ++#endif /* CONFIG_COMPAT */
2102 ++#endif /* __KERNEL__ */
2103 ++
2104 + struct fb_con2fbmap {
2105 + __u32 console;
2106 + __u32 framebuffer;
2107 +@@ -364,6 +421,34 @@ struct fb_image {
2108 + struct fb_cmap cmap; /* color map info */
2109 + };
2110 +
2111 ++#ifdef __KERNEL__
2112 ++#ifdef CONFIG_COMPAT
2113 ++struct fb_image32 {
2114 ++ __u32 dx; /* Where to place image */
2115 ++ __u32 dy;
2116 ++ __u32 width; /* Size of image */
2117 ++ __u32 height;
2118 ++ __u32 fg_color; /* Only used when a mono bitmap */
2119 ++ __u32 bg_color;
2120 ++ __u8 depth; /* Depth of the image */
2121 ++ const compat_uptr_t data; /* Pointer to image data */
2122 ++ struct fb_cmap32 cmap; /* color map info */
2123 ++};
2124 ++
2125 ++#define fb_image_from_compat(to, from) \
2126 ++ (to).dx = (from).dx; \
2127 ++ (to).dy = (from).dy; \
2128 ++ (to).width = (from).width; \
2129 ++ (to).height = (from).height; \
2130 ++ (to).fg_color = (from).fg_color; \
2131 ++ (to).bg_color = (from).bg_color; \
2132 ++ (to).depth = (from).depth; \
2133 ++ (to).data = compat_ptr((from).data); \
2134 ++ fb_cmap_from_compat((to).cmap, (from).cmap)
2135 ++
2136 ++#endif /* CONFIG_COMPAT */
2137 ++#endif /* __KERNEL__ */
2138 ++
2139 + /*
2140 + * hardware cursor control
2141 + */
2142 +@@ -873,6 +958,9 @@ struct fb_info {
2143 + #define FBINFO_STATE_SUSPENDED 1
2144 + u32 state; /* Hardware state i.e suspend */
2145 + void *fbcon_par; /* fbcon use-only private area */
2146 ++
2147 ++ struct fb_image bgdecor;
2148 ++
2149 + /* From here on everything is device dependent */
2150 + void *par;
2151 + /* we need the PCI or similiar aperture base/size not
2152 +diff --git a/kernel/sysctl.c b/kernel/sysctl.c
2153 +index 0f1bd83..91946b3 100644
2154 +--- a/kernel/sysctl.c
2155 ++++ b/kernel/sysctl.c
2156 +@@ -133,6 +133,10 @@ static int min_percpu_pagelist_fract = 8;
2157 +
2158 + static int ngroups_max = NGROUPS_MAX;
2159 +
2160 ++#ifdef CONFIG_FB_CON_DECOR
2161 ++extern char fbcon_decor_path[];
2162 ++#endif
2163 ++
2164 + #ifdef CONFIG_INOTIFY_USER
2165 + #include <linux/inotify.h>
2166 + #endif
2167 +@@ -247,6 +251,15 @@ static struct ctl_table root_table[] = {
2168 + .mode = 0555,
2169 + .child = dev_table,
2170 + },
2171 ++#ifdef CONFIG_FB_CON_DECOR
2172 ++ {
2173 ++ .procname = "fbcondecor",
2174 ++ .data = &fbcon_decor_path,
2175 ++ .maxlen = KMOD_PATH_LEN,
2176 ++ .mode = 0644,
2177 ++ .proc_handler = &proc_dostring,
2178 ++ },
2179 ++#endif
2180 + { }
2181 + };
2182 +
2183 +--
2184 +1.7.4.1
2185 +