Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 452574 | Differences between
and this patch

Collapse All | Expand All

(-)a/Documentation/fb/00-INDEX (+2 lines)
Lines 21-26 ep93xx-fb.txt Link Here
21
	- info on the driver for EP93xx LCD controller.
21
	- info on the driver for EP93xx LCD controller.
22
fbcon.txt
22
fbcon.txt
23
	- intro to and usage guide for the framebuffer console (fbcon).
23
	- intro to and usage guide for the framebuffer console (fbcon).
24
fbcondecor.txt
25
	- info on the Framebuffer Console Decoration
24
framebuffer.txt
26
framebuffer.txt
25
	- introduction to frame buffer devices.
27
	- introduction to frame buffer devices.
26
gxfb.txt
28
gxfb.txt
(-)a/Documentation/fb/fbcondecor.txt (+207 lines)
Line 0 Link Here
1
What is it?
2
-----------
3
4
The framebuffer decorations are a kernel feature which allows displaying a 
5
background picture on selected consoles.
6
7
What do I need to get it to work?
8
---------------------------------
9
10
To get fbcondecor up-and-running you will have to:
11
 1) get a copy of splashutils [1] or a similar program
12
 2) get some fbcondecor themes
13
 3) build the kernel helper program
14
 4) build your kernel with the FB_CON_DECOR option enabled.
15
16
To get fbcondecor operational right after fbcon initialization is finished, you
17
will have to include a theme and the kernel helper into your initramfs image.
18
Please refer to splashutils documentation for instructions on how to do that.
19
20
[1] The splashutils package can be downloaded from:
21
    http://dev.gentoo.org/~spock/projects/splashutils/
22
23
The userspace helper
24
--------------------
25
26
The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the
27
kernel whenever an important event occurs and the kernel needs some kind of
28
job to be carried out. Important events include console switches and video
29
mode switches (the kernel requests background images and configuration
30
parameters for the current console). The fbcondecor helper must be accessible at
31
all times. If it's not, fbcondecor will be switched off automatically.
32
33
It's possible to set path to the fbcondecor helper by writing it to
34
/proc/sys/kernel/fbcondecor.
35
36
*****************************************************************************
37
38
The information below is mostly technical stuff. There's probably no need to
39
read it unless you plan to develop a userspace helper.
40
41
The fbcondecor protocol
42
-----------------------
43
44
The fbcondecor protocol defines a communication interface between the kernel and
45
the userspace fbcondecor helper.
46
47
The kernel side is responsible for:
48
49
 * rendering console text, using an image as a background (instead of a
50
   standard solid color fbcon uses),
51
 * accepting commands from the user via ioctls on the fbcondecor device,
52
 * calling the userspace helper to set things up as soon as the fb subsystem 
53
   is initialized.
54
55
The userspace helper is responsible for everything else, including parsing
56
configuration files, decompressing the image files whenever the kernel needs
57
it, and communicating with the kernel if necessary.
58
59
The fbcondecor protocol specifies how communication is done in both ways:
60
kernel->userspace and userspace->helper.
61
  
62
Kernel -> Userspace
63
-------------------
64
65
The kernel communicates with the userspace helper by calling it and specifying
66
the task to be done in a series of arguments.
67
68
The arguments follow the pattern:
69
<fbcondecor protocol version> <command> <parameters>
70
71
All commands defined in fbcondecor protocol v2 have the following parameters:
72
 virtual console
73
 framebuffer number
74
 theme
75
76
Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the
77
framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used.
78
79
Fbcondecor protocol v2 specifies the following commands:
80
81
getpic
82
------
83
 The kernel issues this command to request image data. It's up to the 
84
 userspace  helper to find a background image appropriate for the specified 
85
 theme and the current resolution. The userspace helper should respond by 
86
 issuing the FBIOCONDECOR_SETPIC ioctl.
87
88
init
89
----
90
 The kernel issues this command after the fbcondecor device is created and
91
 the fbcondecor interface is initialized. Upon receiving 'init', the userspace
92
 helper should parse the kernel command line (/proc/cmdline) or otherwise
93
 decide whether fbcondecor is to be activated.
94
95
 To activate fbcondecor on the first console the helper should issue the
96
 FBIOCONDECOR_SETCFG, FBIOCONDECOR_SETPIC and FBIOCONDECOR_SETSTATE commands,
97
 in the above-mentioned order.
98
99
 When the userspace helper is called in an early phase of the boot process
100
 (right after the initialization of fbcon), no filesystems will be mounted.
101
 The helper program should mount sysfs and then create the appropriate
102
 framebuffer, fbcondecor and tty0 devices (if they don't already exist) to get
103
 current display settings and to be able to communicate with the kernel side.
104
 It should probably also mount the procfs to be able to parse the kernel
105
 command line parameters.
106
107
 Note that the console sem is not held when the kernel calls fbcondecor_helper
108
 with the 'init' command. The fbcondecor helper should perform all ioctls with
109
 origin set to FBCON_DECOR_IO_ORIG_USER.
110
111
modechange
112
----------
113
 The kernel issues this command on a mode change. The helper's response should
114
 be similar to the response to the 'init' command. Note that this time the
115
 console sem is held and all ioctls must be performed with origin set to
116
 FBCON_DECOR_IO_ORIG_KERNEL.
117
118
119
Userspace -> Kernel
120
-------------------
121
122
Userspace programs can communicate with fbcondecor via ioctls on the
123
fbcondecor device. These ioctls are to be used by both the userspace helper
124
(called only by the kernel) and userspace configuration tools (run by the users).
125
126
The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL
127
when doing the appropriate ioctls. All userspace configuration tools should
128
use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin
129
field when performing ioctls from the kernel helper will most likely result
130
in a console deadlock.
131
132
FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console
133
semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire
134
the console sem.
135
136
The framebuffer console decoration provides the following ioctls (all defined in 
137
linux/fb.h):
138
139
FBIOCONDECOR_SETPIC
140
description: loads a background picture for a virtual console
141
argument: struct fbcon_decor_iowrapper*; data: struct fb_image*
142
notes: 
143
If called for consoles other than the current foreground one, the picture data
144
will be ignored.
145
146
If the current virtual console is running in a 8-bpp mode, the cmap substruct
147
of fb_image has to be filled appropriately: start should be set to 16 (first
148
16 colors are reserved for fbcon), len to a value <= 240 and red, green and
149
blue should point to valid cmap data. The transp field is ingored. The fields
150
dx, dy, bg_color, fg_color in fb_image are ignored as well.
151
152
FBIOCONDECOR_SETCFG
153
description: sets the fbcondecor config for a virtual console
154
argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
155
notes: The structure has to be filled with valid data.
156
157
FBIOCONDECOR_GETCFG
158
description: gets the fbcondecor config for a virtual console
159
argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
160
161
FBIOCONDECOR_SETSTATE
162
description: sets the fbcondecor state for a virtual console
163
argument: struct fbcon_decor_iowrapper*; data: unsigned int*
164
          values: 0 = disabled, 1 = enabled.
165
166
FBIOCONDECOR_GETSTATE
167
description: gets the fbcondecor state for a virtual console
168
argument: struct fbcon_decor_iowrapper*; data: unsigned int*
169
          values: as in FBIOCONDECOR_SETSTATE
170
171
Info on used structures:
172
173
Definition of struct vc_decor can be found in linux/console_decor.h. It's
174
heavily commented. Note that the 'theme' field should point to a string
175
no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is
176
performed, the theme field should point to a char buffer of length
177
FBCON_DECOR_THEME_LEN.
178
179
Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h.
180
The fields in this struct have the following meaning:
181
182
vc: 
183
Virtual console number.
184
185
origin: 
186
Specifies if the ioctl is performed as a response to a kernel request. The
187
fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace
188
programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to
189
avoid console semaphore deadlocks.
190
191
data: 
192
Pointer to a data structure appropriate for the performed ioctl. Type of
193
the data struct is specified in the ioctls description.
194
195
*****************************************************************************
196
197
Credit
198
------
199
200
Original 'bootsplash' project & implementation by:
201
  Volker Poplawski <volker@poplawski.de>, Stefan Reinauer <stepan@suse.de>,
202
  Steffen Winterfeldt <snwint@suse.de>, Michael Schroeder <mls@suse.de>,
203
  Ken Wimer <wimer@suse.de>.
204
205
Fbcondecor, fbcondecor protocol design, current implementation & docs by:
206
  Michal Januszewski <spock@gentoo.org>
207
(-)a/drivers/Makefile (-5 / +4 lines)
Lines 11-16 obj-y += gpio/ Link Here
11
obj-$(CONFIG_PCI)		+= pci/
11
obj-$(CONFIG_PCI)		+= pci/
12
obj-$(CONFIG_PARISC)		+= parisc/
12
obj-$(CONFIG_PARISC)		+= parisc/
13
obj-$(CONFIG_RAPIDIO)		+= rapidio/
13
obj-$(CONFIG_RAPIDIO)		+= rapidio/
14
# tty/ comes before char/ so that the VT console is the boot-time
15
# default.
16
obj-y				+= tty/
17
obj-y				+= char/
14
obj-y				+= video/
18
obj-y				+= video/
15
obj-y				+= idle/
19
obj-y				+= idle/
16
obj-$(CONFIG_ACPI)		+= acpi/
20
obj-$(CONFIG_ACPI)		+= acpi/
Lines 29-39 obj-$(CONFIG_XEN) += xen/ Link Here
29
# regulators early, since some subsystems rely on them to initialize
33
# regulators early, since some subsystems rely on them to initialize
30
obj-$(CONFIG_REGULATOR)		+= regulator/
34
obj-$(CONFIG_REGULATOR)		+= regulator/
31
35
32
# tty/ comes before char/ so that the VT console is the boot-time
33
# default.
34
obj-y				+= tty/
35
obj-y				+= char/
36
37
# gpu/ comes after char for AGP vs DRM startup
36
# gpu/ comes after char for AGP vs DRM startup
38
obj-y				+= gpu/
37
obj-y				+= gpu/
39
38
(-)a/drivers/video/Kconfig (-1 lines)
Lines 1241-1247 config FB_MATROX Link Here
1241
	select FB_CFB_FILLRECT
1241
	select FB_CFB_FILLRECT
1242
	select FB_CFB_COPYAREA
1242
	select FB_CFB_COPYAREA
1243
	select FB_CFB_IMAGEBLIT
1243
	select FB_CFB_IMAGEBLIT
1244
	select FB_TILEBLITTING
1245
	select FB_MACMODES if PPC_PMAC
1244
	select FB_MACMODES if PPC_PMAC
1246
	---help---
1245
	---help---
1247
	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
1246
	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
(-)a/drivers/video/console/Kconfig (+13 lines)
Lines 120-125 config FRAMEBUFFER_CONSOLE_ROTATION Link Here
120
         such that other users of the framebuffer will remain normally
120
         such that other users of the framebuffer will remain normally
121
         oriented.
121
         oriented.
122
122
123
config FB_CON_DECOR
124
	bool "Support for the Framebuffer Console Decorations"
125
	depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
126
	default n
127
	---help---
128
	  This option enables support for framebuffer console decorations which
129
	  makes it possible to display images in the background of the system
130
	  consoles.  Note that userspace utilities are necessary in order to take 
131
	  advantage of these features. Refer to Documentation/fb/fbcondecor.txt 
132
	  for more information.
133
134
	  If unsure, say N.
135
123
config STI_CONSOLE
136
config STI_CONSOLE
124
        bool "STI text console"
137
        bool "STI text console"
125
        depends on PARISC
138
        depends on PARISC
(-)a/drivers/video/console/Makefile (+1 lines)
Lines 34-39 obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \ Link Here
34
                                         fbcon_ccw.o
34
                                         fbcon_ccw.o
35
endif
35
endif
36
36
37
obj-$(CONFIG_FB_CON_DECOR)     	  += fbcondecor.o cfbcondecor.o
37
obj-$(CONFIG_FB_STI)              += sticore.o font.o
38
obj-$(CONFIG_FB_STI)              += sticore.o font.o
38
39
39
ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
40
ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
(-)a/drivers/video/console/bitblit.c (-4 / +16 lines)
Lines 18-23 Link Here
18
#include <linux/console.h>
18
#include <linux/console.h>
19
#include <asm/types.h>
19
#include <asm/types.h>
20
#include "fbcon.h"
20
#include "fbcon.h"
21
#include "fbcondecor.h"
21
22
22
/*
23
/*
23
 * Accelerated handlers.
24
 * Accelerated handlers.
Lines 55-60 static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy, Link Here
55
	area.height = height * vc->vc_font.height;
56
	area.height = height * vc->vc_font.height;
56
	area.width = width * vc->vc_font.width;
57
	area.width = width * vc->vc_font.width;
57
58
59
	if (fbcon_decor_active(info, vc)) {
60
 		area.sx += vc->vc_decor.tx;
61
 		area.sy += vc->vc_decor.ty;
62
 		area.dx += vc->vc_decor.tx;
63
 		area.dy += vc->vc_decor.ty;
64
 	}
65
58
	info->fbops->fb_copyarea(info, &area);
66
	info->fbops->fb_copyarea(info, &area);
59
}
67
}
60
68
Lines 380-390 static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, Link Here
380
	cursor.image.depth = 1;
388
	cursor.image.depth = 1;
381
	cursor.rop = ROP_XOR;
389
	cursor.rop = ROP_XOR;
382
390
383
	if (info->fbops->fb_cursor)
391
	if (fbcon_decor_active(info, vc)) {
384
		err = info->fbops->fb_cursor(info, &cursor);
392
		fbcon_decor_cursor(info, &cursor);
393
	} else {
394
		if (info->fbops->fb_cursor)
395
			err = info->fbops->fb_cursor(info, &cursor);
385
396
386
	if (err)
397
		if (err)
387
		soft_cursor(info, &cursor);
398
			soft_cursor(info, &cursor);
399
	}
388
400
389
	ops->cursor_reset = 0;
401
	ops->cursor_reset = 0;
390
}
402
}
(-)a/drivers/video/console/cfbcondecor.c (+471 lines)
Line 0 Link Here
1
/*
2
 *  linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions
3
 *
4
 *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
5
 *
6
 *  Code based upon "Bootdecor" (C) 2001-2003
7
 *       Volker Poplawski <volker@poplawski.de>,
8
 *       Stefan Reinauer <stepan@suse.de>,
9
 *       Steffen Winterfeldt <snwint@suse.de>,
10
 *       Michael Schroeder <mls@suse.de>,
11
 *       Ken Wimer <wimer@suse.de>.
12
 *
13
 *  This file is subject to the terms and conditions of the GNU General Public
14
 *  License.  See the file COPYING in the main directory of this archive for
15
 *  more details.
16
 */
17
#include <linux/module.h>
18
#include <linux/types.h>
19
#include <linux/fb.h>
20
#include <linux/selection.h>
21
#include <linux/slab.h>
22
#include <linux/vt_kern.h>
23
#include <asm/irq.h>
24
25
#include "fbcon.h"
26
#include "fbcondecor.h"
27
28
#define parse_pixel(shift,bpp,type)						\
29
	do {									\
30
		if (d & (0x80 >> (shift)))					\
31
			dd2[(shift)] = fgx;					\
32
		else								\
33
			dd2[(shift)] = transparent ? *(type *)decor_src : bgx;	\
34
		decor_src += (bpp);						\
35
	} while (0)								\
36
37
extern int get_color(struct vc_data *vc, struct fb_info *info,
38
		     u16 c, int is_fg);
39
40
void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc)
41
{
42
	int i, j, k;
43
	int minlen = min(min(info->var.red.length, info->var.green.length),
44
			     info->var.blue.length);
45
	u32 col;
46
47
	for (j = i = 0; i < 16; i++) {
48
		k = color_table[i];
49
50
		col = ((vc->vc_palette[j++]  >> (8-minlen))
51
			<< info->var.red.offset);
52
		col |= ((vc->vc_palette[j++] >> (8-minlen))
53
			<< info->var.green.offset);
54
		col |= ((vc->vc_palette[j++] >> (8-minlen))
55
			<< info->var.blue.offset);
56
			((u32 *)info->pseudo_palette)[k] = col;
57
	}
58
}
59
60
void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height,
61
		      int width, u8* src, u32 fgx, u32 bgx, u8 transparent)
62
{
63
	unsigned int x, y;
64
	u32 dd;
65
	int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
66
	unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
67
	unsigned int ds = (ypos * info->var.xres + xpos) * bytespp;
68
	u16 dd2[4];
69
70
	u8* decor_src = (u8 *)(info->bgdecor.data + ds);
71
	u8* dst = (u8 *)(info->screen_base + d);
72
73
	if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
74
		return;
75
76
	for (y = 0; y < height; y++) {
77
		switch (info->var.bits_per_pixel) {
78
79
		case 32:
80
			for (x = 0; x < width; x++) {
81
82
				if ((x & 7) == 0)
83
					d = *src++;
84
				if (d & 0x80)
85
					dd = fgx;
86
				else
87
					dd = transparent ?
88
					     *(u32 *)decor_src : bgx;
89
90
				d <<= 1;
91
				decor_src += 4;
92
				fb_writel(dd, dst);
93
				dst += 4;
94
			}
95
			break;
96
		case 24:
97
			for (x = 0; x < width; x++) {
98
99
				if ((x & 7) == 0)
100
					d = *src++;
101
				if (d & 0x80)
102
					dd = fgx;
103
				else
104
					dd = transparent ?
105
					     (*(u32 *)decor_src & 0xffffff) : bgx;
106
107
				d <<= 1;
108
				decor_src += 3;
109
#ifdef __LITTLE_ENDIAN
110
				fb_writew(dd & 0xffff, dst);
111
				dst += 2;
112
				fb_writeb((dd >> 16), dst);
113
#else
114
				fb_writew(dd >> 8, dst);
115
				dst += 2;
116
				fb_writeb(dd & 0xff, dst);
117
#endif
118
				dst++;
119
			}
120
			break;
121
		case 16:
122
			for (x = 0; x < width; x += 2) {
123
				if ((x & 7) == 0)
124
					d = *src++;
125
126
				parse_pixel(0, 2, u16);
127
				parse_pixel(1, 2, u16);
128
#ifdef __LITTLE_ENDIAN
129
				dd = dd2[0] | (dd2[1] << 16);
130
#else
131
				dd = dd2[1] | (dd2[0] << 16);
132
#endif
133
				d <<= 2;
134
				fb_writel(dd, dst);
135
				dst += 4;
136
			}
137
			break;
138
139
		case 8:
140
			for (x = 0; x < width; x += 4) {
141
				if ((x & 7) == 0)
142
					d = *src++;
143
144
				parse_pixel(0, 1, u8);
145
				parse_pixel(1, 1, u8);
146
				parse_pixel(2, 1, u8);
147
				parse_pixel(3, 1, u8);
148
149
#ifdef __LITTLE_ENDIAN
150
				dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
151
#else
152
				dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
153
#endif
154
				d <<= 4;
155
				fb_writel(dd, dst);
156
				dst += 4;
157
			}
158
		}
159
160
		dst += info->fix.line_length - width * bytespp;
161
		decor_src += (info->var.xres - width) * bytespp;
162
	}
163
}
164
165
#define cc2cx(a) 						\
166
	((info->fix.visual == FB_VISUAL_TRUECOLOR || 		\
167
	  info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? 		\
168
	 ((u32*)info->pseudo_palette)[a] : a)
169
170
void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info,
171
		   const unsigned short *s, int count, int yy, int xx)
172
{
173
	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
174
	struct fbcon_ops *ops = info->fbcon_par;
175
	int fg_color, bg_color, transparent;
176
	u8 *src;
177
	u32 bgx, fgx;
178
	u16 c = scr_readw(s);
179
180
	fg_color = get_color(vc, info, c, 1);
181
        bg_color = get_color(vc, info, c, 0);
182
183
	/* Don't paint the background image if console is blanked */
184
	transparent = ops->blank_state ? 0 :
185
		(vc->vc_decor.bg_color == bg_color);
186
187
	xx = xx * vc->vc_font.width + vc->vc_decor.tx;
188
	yy = yy * vc->vc_font.height + vc->vc_decor.ty;
189
190
	fgx = cc2cx(fg_color);
191
	bgx = cc2cx(bg_color);
192
193
	while (count--) {
194
		c = scr_readw(s++);
195
		src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
196
		      ((vc->vc_font.width + 7) >> 3);
197
198
		fbcon_decor_renderc(info, yy, xx, vc->vc_font.height,
199
			       vc->vc_font.width, src, fgx, bgx, transparent);
200
		xx += vc->vc_font.width;
201
	}
202
}
203
204
void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor)
205
{
206
	int i;
207
	unsigned int dsize, s_pitch;
208
	struct fbcon_ops *ops = info->fbcon_par;
209
	struct vc_data* vc;
210
	u8 *src;
211
212
	/* we really don't need any cursors while the console is blanked */
213
	if (info->state != FBINFO_STATE_RUNNING || ops->blank_state)
214
		return;
215
216
	vc = vc_cons[ops->currcon].d;
217
218
	src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC);
219
	if (!src)
220
		return;
221
222
	s_pitch = (cursor->image.width + 7) >> 3;
223
	dsize = s_pitch * cursor->image.height;
224
	if (cursor->enable) {
225
		switch (cursor->rop) {
226
		case ROP_XOR:
227
			for (i = 0; i < dsize; i++)
228
				src[i] = cursor->image.data[i] ^ cursor->mask[i];
229
                        break;
230
		case ROP_COPY:
231
		default:
232
			for (i = 0; i < dsize; i++)
233
				src[i] = cursor->image.data[i] & cursor->mask[i];
234
			break;
235
		}
236
	} else
237
		memcpy(src, cursor->image.data, dsize);
238
239
	fbcon_decor_renderc(info,
240
			cursor->image.dy + vc->vc_decor.ty,
241
			cursor->image.dx + vc->vc_decor.tx,
242
			cursor->image.height,
243
			cursor->image.width,
244
			(u8*)src,
245
			cc2cx(cursor->image.fg_color),
246
			cc2cx(cursor->image.bg_color),
247
			cursor->image.bg_color == vc->vc_decor.bg_color);
248
249
	kfree(src);
250
}
251
252
static void decorset(u8 *dst, int height, int width, int dstbytes,
253
		        u32 bgx, int bpp)
254
{
255
	int i;
256
257
	if (bpp == 8)
258
		bgx |= bgx << 8;
259
	if (bpp == 16 || bpp == 8)
260
		bgx |= bgx << 16;
261
262
	while (height-- > 0) {
263
		u8 *p = dst;
264
265
		switch (bpp) {
266
267
		case 32:
268
			for (i=0; i < width; i++) {
269
				fb_writel(bgx, p); p += 4;
270
			}
271
			break;
272
		case 24:
273
			for (i=0; i < width; i++) {
274
#ifdef __LITTLE_ENDIAN
275
				fb_writew((bgx & 0xffff),(u16*)p); p += 2;
276
				fb_writeb((bgx >> 16),p++);
277
#else
278
				fb_writew((bgx >> 8),(u16*)p); p += 2;
279
				fb_writeb((bgx & 0xff),p++);
280
#endif
281
			}
282
		case 16:
283
			for (i=0; i < width/4; i++) {
284
				fb_writel(bgx,p); p += 4;
285
				fb_writel(bgx,p); p += 4;
286
			}
287
			if (width & 2) {
288
				fb_writel(bgx,p); p += 4;
289
			}
290
			if (width & 1)
291
				fb_writew(bgx,(u16*)p);
292
			break;
293
		case 8:
294
			for (i=0; i < width/4; i++) {
295
				fb_writel(bgx,p); p += 4;
296
			}
297
298
			if (width & 2) {
299
				fb_writew(bgx,p); p += 2;
300
			}
301
			if (width & 1)
302
				fb_writeb(bgx,(u8*)p);
303
			break;
304
305
		}
306
		dst += dstbytes;
307
	}
308
}
309
310
void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
311
		   int srclinebytes, int bpp)
312
{
313
	int i;
314
315
	while (height-- > 0) {
316
		u32 *p = (u32 *)dst;
317
		u32 *q = (u32 *)src;
318
319
		switch (bpp) {
320
321
		case 32:
322
			for (i=0; i < width; i++)
323
				fb_writel(*q++, p++);
324
			break;
325
		case 24:
326
			for (i=0; i < (width*3/4); i++)
327
				fb_writel(*q++, p++);
328
			if ((width*3) % 4) {
329
				if (width & 2) {
330
					fb_writeb(*(u8*)q, (u8*)p);
331
				} else if (width & 1) {
332
					fb_writew(*(u16*)q, (u16*)p);
333
					fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2));
334
				}
335
			}
336
			break;
337
		case 16:
338
			for (i=0; i < width/4; i++) {
339
				fb_writel(*q++, p++);
340
				fb_writel(*q++, p++);
341
			}
342
			if (width & 2)
343
				fb_writel(*q++, p++);
344
			if (width & 1)
345
				fb_writew(*(u16*)q, (u16*)p);
346
			break;
347
		case 8:
348
			for (i=0; i < width/4; i++)
349
				fb_writel(*q++, p++);
350
351
			if (width & 2) {
352
				fb_writew(*(u16*)q, (u16*)p);
353
				q = (u32*) ((u16*)q + 1);
354
				p = (u32*) ((u16*)p + 1);
355
			}
356
			if (width & 1)
357
				fb_writeb(*(u8*)q, (u8*)p);
358
			break;
359
		}
360
361
		dst += linebytes;
362
		src += srclinebytes;
363
	}
364
}
365
366
static void decorfill(struct fb_info *info, int sy, int sx, int height,
367
		       int width)
368
{
369
	int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
370
	int d  = sy * info->fix.line_length + sx * bytespp;
371
	int ds = (sy * info->var.xres + sx) * bytespp;
372
373
	fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds),
374
		    height, width, info->fix.line_length, info->var.xres * bytespp,
375
		    info->var.bits_per_pixel);
376
}
377
378
void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
379
		    int height, int width)
380
{
381
	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
382
	struct fbcon_ops *ops = info->fbcon_par;
383
	u8 *dst;
384
	int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info);
385
386
	transparent = (vc->vc_decor.bg_color == bg_color);
387
	sy = sy * vc->vc_font.height + vc->vc_decor.ty;
388
	sx = sx * vc->vc_font.width + vc->vc_decor.tx;
389
	height *= vc->vc_font.height;
390
	width *= vc->vc_font.width;
391
392
	/* Don't paint the background image if console is blanked */
393
	if (transparent && !ops->blank_state) {
394
		decorfill(info, sy, sx, height, width);
395
	} else {
396
		dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
397
			     sx * ((info->var.bits_per_pixel + 7) >> 3));
398
		decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
399
			  info->var.bits_per_pixel);
400
	}
401
}
402
403
void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info,
404
			    int bottom_only)
405
{
406
	unsigned int tw = vc->vc_cols*vc->vc_font.width;
407
	unsigned int th = vc->vc_rows*vc->vc_font.height;
408
409
	if (!bottom_only) {
410
		/* top margin */
411
		decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres);
412
		/* left margin */
413
		decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx);
414
		/* right margin */
415
		decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th, 
416
			   info->var.xres - vc->vc_decor.tx - tw);
417
	}
418
	decorfill(info, vc->vc_decor.ty + th, 0, 
419
		   info->var.yres - vc->vc_decor.ty - th, info->var.xres);
420
}
421
422
void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, 
423
			   int sx, int dx, int width)
424
{
425
	u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
426
	u16 *s = d + (dx - sx);
427
	u16 *start = d;
428
	u16 *ls = d;
429
	u16 *le = d + width;
430
	u16 c;
431
	int x = dx;
432
	u16 attr = 1;
433
434
	do {
435
		c = scr_readw(d);
436
		if (attr != (c & 0xff00)) {
437
			attr = c & 0xff00;
438
			if (d > start) {
439
				fbcon_decor_putcs(vc, info, start, d - start, y, x);
440
				x += d - start;
441
				start = d;
442
			}
443
		}
444
		if (s >= ls && s < le && c == scr_readw(s)) {
445
			if (d > start) {
446
				fbcon_decor_putcs(vc, info, start, d - start, y, x);
447
				x += d - start + 1;
448
				start = d + 1;
449
			} else {
450
				x++;
451
				start++;
452
			}
453
		}
454
		s++;
455
		d++;
456
	} while (d < le);
457
	if (d > start)
458
		fbcon_decor_putcs(vc, info, start, d - start, y, x);
459
}
460
461
void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank)
462
{
463
	if (blank) {
464
		decorset((u8 *)info->screen_base, info->var.yres, info->var.xres,
465
			  info->fix.line_length, 0, info->var.bits_per_pixel);
466
	} else {
467
		update_screen(vc);
468
		fbcon_decor_clear_margins(vc, info, 0);
469
	}
470
}
471
(-)a/drivers/video/console/fbcon.c (-42 / +169 lines)
Lines 26-32 Link Here
26
 *
26
 *
27
 *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
27
 *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
28
 *  Smart redraw scrolling, arbitrary font width support, 512char font support
28
 *  Smart redraw scrolling, arbitrary font width support, 512char font support
29
 *  and software scrollback added by 
29
 *  and software scrollback added by
30
 *                         Jakub Jelinek (jj@ultra.linux.cz)
30
 *                         Jakub Jelinek (jj@ultra.linux.cz)
31
 *
31
 *
32
 *  Random hacking by Martin Mares <mj@ucw.cz>
32
 *  Random hacking by Martin Mares <mj@ucw.cz>
Lines 79-84 Link Here
79
#include <asm/irq.h>
79
#include <asm/irq.h>
80
80
81
#include "fbcon.h"
81
#include "fbcon.h"
82
#include "fbcondecor.h"
82
83
83
#ifdef FBCONDEBUG
84
#ifdef FBCONDEBUG
84
#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
85
#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
Lines 94-100 enum { Link Here
94
95
95
static struct display fb_display[MAX_NR_CONSOLES];
96
static struct display fb_display[MAX_NR_CONSOLES];
96
97
97
static signed char con2fb_map[MAX_NR_CONSOLES];
98
signed char con2fb_map[MAX_NR_CONSOLES];
98
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
99
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
99
100
100
static int logo_lines;
101
static int logo_lines;
Lines 110-116 static int softback_lines; Link Here
110
/* console mappings */
111
/* console mappings */
111
static int first_fb_vc;
112
static int first_fb_vc;
112
static int last_fb_vc = MAX_NR_CONSOLES - 1;
113
static int last_fb_vc = MAX_NR_CONSOLES - 1;
113
static int fbcon_is_default = 1; 
114
static int fbcon_is_default = 1;
114
static int fbcon_has_exited;
115
static int fbcon_has_exited;
115
static int primary_device = -1;
116
static int primary_device = -1;
116
static int fbcon_has_console_bind;
117
static int fbcon_has_console_bind;
Lines 286-292 static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) Link Here
286
		!vt_force_oops_output(vc);
287
		!vt_force_oops_output(vc);
287
}
288
}
288
289
289
static int get_color(struct vc_data *vc, struct fb_info *info,
290
int get_color(struct vc_data *vc, struct fb_info *info,
290
	      u16 c, int is_fg)
291
	      u16 c, int is_fg)
291
{
292
{
292
	int depth = fb_get_color_depth(&info->var, &info->fix);
293
	int depth = fb_get_color_depth(&info->var, &info->fix);
Lines 458-464 static int __init fb_console_setup(char *this_opt) Link Here
458
			} else
459
			} else
459
				return 1;
460
				return 1;
460
		}
461
		}
461
		
462
462
		if (!strncmp(options, "map:", 4)) {
463
		if (!strncmp(options, "map:", 4)) {
463
			options += 4;
464
			options += 4;
464
			if (*options) {
465
			if (*options) {
Lines 483-490 static int __init fb_console_setup(char *this_opt) Link Here
483
				first_fb_vc = 0;
484
				first_fb_vc = 0;
484
			if (*options++ == '-')
485
			if (*options++ == '-')
485
				last_fb_vc = simple_strtoul(options, &options, 10) - 1;
486
				last_fb_vc = simple_strtoul(options, &options, 10) - 1;
486
			fbcon_is_default = 0; 
487
			fbcon_is_default = 0;
487
		}	
488
		}
488
489
489
		if (!strncmp(options, "rotate:", 7)) {
490
		if (!strncmp(options, "rotate:", 7)) {
490
			options += 7;
491
			options += 7;
Lines 545-550 static int fbcon_takeover(int show_logo) Link Here
545
		info_idx = -1;
546
		info_idx = -1;
546
	} else {
547
	} else {
547
		fbcon_has_console_bind = 1;
548
		fbcon_has_console_bind = 1;
549
#ifdef CONFIG_FB_CON_DECOR
550
		fbcon_decor_init();
551
#endif
548
	}
552
	}
549
553
550
	return err;
554
	return err;
Lines 935-941 static const char *fbcon_startup(void) Link Here
935
	info = registered_fb[info_idx];
939
	info = registered_fb[info_idx];
936
	if (!info)
940
	if (!info)
937
		return NULL;
941
		return NULL;
938
	
942
939
	owner = info->fbops->owner;
943
	owner = info->fbops->owner;
940
	if (!try_module_get(owner))
944
	if (!try_module_get(owner))
941
		return NULL;
945
		return NULL;
Lines 999-1004 static const char *fbcon_startup(void) Link Here
999
	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1003
	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1000
	cols /= vc->vc_font.width;
1004
	cols /= vc->vc_font.width;
1001
	rows /= vc->vc_font.height;
1005
	rows /= vc->vc_font.height;
1006
1007
	if (fbcon_decor_active(info, vc)) {
1008
		cols = vc->vc_decor.twidth / vc->vc_font.width;
1009
		rows = vc->vc_decor.theight / vc->vc_font.height;
1010
	}
1011
1002
	vc_resize(vc, cols, rows);
1012
	vc_resize(vc, cols, rows);
1003
1013
1004
	DPRINTK("mode:   %s\n", info->fix.id);
1014
	DPRINTK("mode:   %s\n", info->fix.id);
Lines 1028-1034 static void fbcon_init(struct vc_data *vc, int init) Link Here
1028
	cap = info->flags;
1038
	cap = info->flags;
1029
1039
1030
	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1040
	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1031
	    (info->fix.type == FB_TYPE_TEXT))
1041
	    (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
1032
		logo = 0;
1042
		logo = 0;
1033
1043
1034
	if (var_to_display(p, &info->var, info))
1044
	if (var_to_display(p, &info->var, info))
Lines 1238-1243 static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, Link Here
1238
	if (sy < vc->vc_top && vc->vc_top == logo_lines)
1248
	if (sy < vc->vc_top && vc->vc_top == logo_lines)
1239
		vc->vc_top = 0;
1249
		vc->vc_top = 0;
1240
1250
1251
 	if (fbcon_decor_active(info, vc)) {
1252
 		fbcon_decor_clear(vc, info, sy, sx, height, width);
1253
 		return;
1254
 	}
1255
1241
	/* Split blits that cross physical y_wrap boundary */
1256
	/* Split blits that cross physical y_wrap boundary */
1242
1257
1243
	y_break = p->vrows - p->yscroll;
1258
	y_break = p->vrows - p->yscroll;
Lines 1257-1266 static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, Link Here
1257
	struct display *p = &fb_display[vc->vc_num];
1272
	struct display *p = &fb_display[vc->vc_num];
1258
	struct fbcon_ops *ops = info->fbcon_par;
1273
	struct fbcon_ops *ops = info->fbcon_par;
1259
1274
1260
	if (!fbcon_is_inactive(vc, info))
1275
	if (!fbcon_is_inactive(vc, info)) {
1261
		ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1276
1262
			   get_color(vc, info, scr_readw(s), 1),
1277
		if (fbcon_decor_active(info, vc))
1263
			   get_color(vc, info, scr_readw(s), 0));
1278
			fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
1279
		else
1280
			ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1281
				   get_color(vc, info, scr_readw(s), 1),
1282
				   get_color(vc, info, scr_readw(s), 0));
1283
	}
1264
}
1284
}
1265
1285
1266
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
1286
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
Lines 1276-1283 static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) Link Here
1276
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1296
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1277
	struct fbcon_ops *ops = info->fbcon_par;
1297
	struct fbcon_ops *ops = info->fbcon_par;
1278
1298
1279
	if (!fbcon_is_inactive(vc, info))
1299
	if (!fbcon_is_inactive(vc, info)) {
1280
		ops->clear_margins(vc, info, bottom_only);
1300
	 	if (fbcon_decor_active(info, vc)) {
1301
	 		fbcon_decor_clear_margins(vc, info, bottom_only);
1302
 		} else {
1303
			ops->clear_margins(vc, info, bottom_only);
1304
		}
1305
	}
1281
}
1306
}
1282
1307
1283
static void fbcon_cursor(struct vc_data *vc, int mode)
1308
static void fbcon_cursor(struct vc_data *vc, int mode)
Lines 1387-1393 static __inline__ void ywrap_up(struct vc_data *vc, int count) Link Here
1387
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1412
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1388
	struct fbcon_ops *ops = info->fbcon_par;
1413
	struct fbcon_ops *ops = info->fbcon_par;
1389
	struct display *p = &fb_display[vc->vc_num];
1414
	struct display *p = &fb_display[vc->vc_num];
1390
	
1415
1391
	p->yscroll += count;
1416
	p->yscroll += count;
1392
	if (p->yscroll >= p->vrows)	/* Deal with wrap */
1417
	if (p->yscroll >= p->vrows)	/* Deal with wrap */
1393
		p->yscroll -= p->vrows;
1418
		p->yscroll -= p->vrows;
Lines 1406-1412 static __inline__ void ywrap_down(struct vc_data *vc, int count) Link Here
1406
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1431
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1407
	struct fbcon_ops *ops = info->fbcon_par;
1432
	struct fbcon_ops *ops = info->fbcon_par;
1408
	struct display *p = &fb_display[vc->vc_num];
1433
	struct display *p = &fb_display[vc->vc_num];
1409
	
1434
1410
	p->yscroll -= count;
1435
	p->yscroll -= count;
1411
	if (p->yscroll < 0)	/* Deal with wrap */
1436
	if (p->yscroll < 0)	/* Deal with wrap */
1412
		p->yscroll += p->vrows;
1437
		p->yscroll += p->vrows;
Lines 1473-1479 static __inline__ void ypan_down(struct vc_data *vc, int count) Link Here
1473
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1498
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1474
	struct display *p = &fb_display[vc->vc_num];
1499
	struct display *p = &fb_display[vc->vc_num];
1475
	struct fbcon_ops *ops = info->fbcon_par;
1500
	struct fbcon_ops *ops = info->fbcon_par;
1476
	
1501
1477
	p->yscroll -= count;
1502
	p->yscroll -= count;
1478
	if (p->yscroll < 0) {
1503
	if (p->yscroll < 0) {
1479
		ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
1504
		ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
Lines 1797-1803 static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, Link Here
1797
			count = vc->vc_rows;
1822
			count = vc->vc_rows;
1798
		if (softback_top)
1823
		if (softback_top)
1799
			fbcon_softback_note(vc, t, count);
1824
			fbcon_softback_note(vc, t, count);
1800
		if (logo_shown >= 0)
1825
		if (logo_shown >= 0 || fbcon_decor_active(info, vc))
1801
			goto redraw_up;
1826
			goto redraw_up;
1802
		switch (p->scrollmode) {
1827
		switch (p->scrollmode) {
1803
		case SCROLL_MOVE:
1828
		case SCROLL_MOVE:
Lines 1890-1895 static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, Link Here
1890
			count = vc->vc_rows;
1915
			count = vc->vc_rows;
1891
		if (logo_shown >= 0)
1916
		if (logo_shown >= 0)
1892
			goto redraw_down;
1917
			goto redraw_down;
1918
		if (fbcon_decor_active(info, vc))
1919
			goto redraw_down;
1893
		switch (p->scrollmode) {
1920
		switch (p->scrollmode) {
1894
		case SCROLL_MOVE:
1921
		case SCROLL_MOVE:
1895
			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
1922
			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
Lines 1982-1988 static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, Link Here
1982
{
2009
{
1983
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2010
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1984
	struct display *p = &fb_display[vc->vc_num];
2011
	struct display *p = &fb_display[vc->vc_num];
1985
	
2012
1986
	if (fbcon_is_inactive(vc, info))
2013
	if (fbcon_is_inactive(vc, info))
1987
		return;
2014
		return;
1988
2015
Lines 2000-2006 static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, Link Here
2000
			p->vrows - p->yscroll);
2027
			p->vrows - p->yscroll);
2001
}
2028
}
2002
2029
2003
static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, 
2030
static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,
2004
			    int dy, int dx, int height, int width, u_int y_break)
2031
			    int dy, int dx, int height, int width, u_int y_break)
2005
{
2032
{
2006
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2033
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
Lines 2038-2043 static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s Link Here
2038
		}
2065
		}
2039
		return;
2066
		return;
2040
	}
2067
	}
2068
2069
	if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
2070
 		/* must use slower redraw bmove to keep background pic intact */
2071
 		fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
2072
 		return;
2073
 	}
2074
2041
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2075
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2042
		   height, width);
2076
		   height, width);
2043
}
2077
}
Lines 2089-2095 static void updatescrollmode(struct display *p, Link Here
2089
	}
2123
	}
2090
}
2124
}
2091
2125
2092
static int fbcon_resize(struct vc_data *vc, unsigned int width, 
2126
static int fbcon_resize(struct vc_data *vc, unsigned int width,
2093
			unsigned int height, unsigned int user)
2127
			unsigned int height, unsigned int user)
2094
{
2128
{
2095
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2129
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
Lines 2108-2115 static int fbcon_resize(struct vc_data *vc, unsigned int width, Link Here
2108
	var.yres = virt_h * virt_fh;
2142
	var.yres = virt_h * virt_fh;
2109
	x_diff = info->var.xres - var.xres;
2143
	x_diff = info->var.xres - var.xres;
2110
	y_diff = info->var.yres - var.yres;
2144
	y_diff = info->var.yres - var.yres;
2111
	if (x_diff < 0 || x_diff > virt_fw ||
2145
	if ((x_diff < 0 || x_diff > virt_fw ||
2112
	    y_diff < 0 || y_diff > virt_fh) {
2146
		y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
2113
		const struct fb_videomode *mode;
2147
		const struct fb_videomode *mode;
2114
2148
2115
		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
2149
		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
Lines 2145-2150 static int fbcon_switch(struct vc_data *vc) Link Here
2145
2179
2146
	info = registered_fb[con2fb_map[vc->vc_num]];
2180
	info = registered_fb[con2fb_map[vc->vc_num]];
2147
	ops = info->fbcon_par;
2181
	ops = info->fbcon_par;
2182
	prev_console = ops->currcon;
2183
	if (prev_console != -1)
2184
		old_info = registered_fb[con2fb_map[prev_console]];
2185
2186
#ifdef CONFIG_FB_CON_DECOR
2187
	if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2188
		struct vc_data *vc_curr = vc_cons[prev_console].d;
2189
		if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
2190
			/* Clear the screen to avoid displaying funky colors during
2191
			 * palette updates. */
2192
			memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset,
2193
			       0, info->var.yres * info->fix.line_length);
2194
		}
2195
	}
2196
#endif
2148
2197
2149
	if (softback_top) {
2198
	if (softback_top) {
2150
		if (softback_lines)
2199
		if (softback_lines)
Lines 2163-2171 static int fbcon_switch(struct vc_data *vc) Link Here
2163
		logo_shown = FBCON_LOGO_CANSHOW;
2212
		logo_shown = FBCON_LOGO_CANSHOW;
2164
	}
2213
	}
2165
2214
2166
	prev_console = ops->currcon;
2167
	if (prev_console != -1)
2168
		old_info = registered_fb[con2fb_map[prev_console]];
2169
	/*
2215
	/*
2170
	 * FIXME: If we have multiple fbdev's loaded, we need to
2216
	 * FIXME: If we have multiple fbdev's loaded, we need to
2171
	 * update all info->currcon.  Perhaps, we can place this
2217
	 * update all info->currcon.  Perhaps, we can place this
Lines 2209-2214 static int fbcon_switch(struct vc_data *vc) Link Here
2209
			fbcon_del_cursor_timer(old_info);
2255
			fbcon_del_cursor_timer(old_info);
2210
	}
2256
	}
2211
2257
2258
	if (fbcon_decor_active_vc(vc)) {
2259
		struct vc_data *vc_curr = vc_cons[prev_console].d;
2260
2261
		if (!vc_curr->vc_decor.theme ||
2262
			strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
2263
			(fbcon_decor_active_nores(info, vc_curr) &&
2264
			 !fbcon_decor_active(info, vc_curr))) {
2265
			fbcon_decor_disable(vc, 0);
2266
			fbcon_decor_call_helper("modechange", vc->vc_num);
2267
		}
2268
	}
2269
2212
	if (fbcon_is_inactive(vc, info) ||
2270
	if (fbcon_is_inactive(vc, info) ||
2213
	    ops->blank_state != FB_BLANK_UNBLANK)
2271
	    ops->blank_state != FB_BLANK_UNBLANK)
2214
		fbcon_del_cursor_timer(info);
2272
		fbcon_del_cursor_timer(info);
Lines 2257-2267 static int fbcon_switch(struct vc_data *vc) Link Here
2257
	    ops->update_start(info);
2315
	    ops->update_start(info);
2258
	}
2316
	}
2259
2317
2260
	fbcon_set_palette(vc, color_table); 	
2318
	fbcon_set_palette(vc, color_table);
2261
	fbcon_clear_margins(vc, 0);
2319
	fbcon_clear_margins(vc, 0);
2262
2320
2263
	if (logo_shown == FBCON_LOGO_DRAW) {
2321
	if (logo_shown == FBCON_LOGO_DRAW) {
2264
2265
		logo_shown = fg_console;
2322
		logo_shown = fg_console;
2266
		/* This is protected above by initmem_freed */
2323
		/* This is protected above by initmem_freed */
2267
		fb_show_logo(info, ops->rotate);
2324
		fb_show_logo(info, ops->rotate);
Lines 2317-2331 static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) Link Here
2317
		}
2374
		}
2318
	}
2375
	}
2319
2376
2320
 	if (!fbcon_is_inactive(vc, info)) {
2377
	if (!fbcon_is_inactive(vc, info)) {
2321
		if (ops->blank_state != blank) {
2378
		if (ops->blank_state != blank) {
2322
			ops->blank_state = blank;
2379
			ops->blank_state = blank;
2323
			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2380
			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2324
			ops->cursor_flash = (!blank);
2381
			ops->cursor_flash = (!blank);
2325
2382
2326
			if (!(info->flags & FBINFO_MISC_USEREVENT))
2383
			if (!(info->flags & FBINFO_MISC_USEREVENT)) {
2327
				if (fb_blank(info, blank))
2384
				if (fb_blank(info, blank)) {
2328
					fbcon_generic_blank(vc, info, blank);
2385
					if (fbcon_decor_active(info, vc))
2386
						fbcon_decor_blank(vc, info, blank);
2387
					else
2388
						fbcon_generic_blank(vc, info, blank);
2389
				}
2390
			}
2329
		}
2391
		}
2330
2392
2331
		if (!blank)
2393
		if (!blank)
Lines 2447-2453 static int fbcon_do_set_font(struct vc_data *vc, int w, int h, Link Here
2447
			vc->vc_complement_mask >>= 1;
2509
			vc->vc_complement_mask >>= 1;
2448
			vc->vc_s_complement_mask >>= 1;
2510
			vc->vc_s_complement_mask >>= 1;
2449
		}
2511
		}
2450
			
2512
2451
		/* ++Edmund: reorder the attribute bits */
2513
		/* ++Edmund: reorder the attribute bits */
2452
		if (vc->vc_can_do_color) {
2514
		if (vc->vc_can_do_color) {
2453
			unsigned short *cp =
2515
			unsigned short *cp =
Lines 2470-2476 static int fbcon_do_set_font(struct vc_data *vc, int w, int h, Link Here
2470
			vc->vc_complement_mask <<= 1;
2532
			vc->vc_complement_mask <<= 1;
2471
			vc->vc_s_complement_mask <<= 1;
2533
			vc->vc_s_complement_mask <<= 1;
2472
		}
2534
		}
2473
			
2535
2474
		/* ++Edmund: reorder the attribute bits */
2536
		/* ++Edmund: reorder the attribute bits */
2475
		{
2537
		{
2476
			unsigned short *cp =
2538
			unsigned short *cp =
Lines 2500-2512 static int fbcon_do_set_font(struct vc_data *vc, int w, int h, Link Here
2500
	}
2562
	}
2501
2563
2502
	if (resize) {
2564
	if (resize) {
2565
		/* reset wrap/pan */
2503
		int cols, rows;
2566
		int cols, rows;
2504
2567
2505
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2568
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2506
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2569
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2570
2571
		if (fbcon_decor_active(info, vc)) {
2572
			info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2573
			cols = vc->vc_decor.twidth;
2574
			rows = vc->vc_decor.theight;
2575
		}
2507
		cols /= w;
2576
		cols /= w;
2508
		rows /= h;
2577
		rows /= h;
2578
2509
		vc_resize(vc, cols, rows);
2579
		vc_resize(vc, cols, rows);
2580
2510
		if (CON_IS_VISIBLE(vc) && softback_buf)
2581
		if (CON_IS_VISIBLE(vc) && softback_buf)
2511
			fbcon_update_softback(vc);
2582
			fbcon_update_softback(vc);
2512
	} else if (CON_IS_VISIBLE(vc)
2583
	} else if (CON_IS_VISIBLE(vc)
Lines 2590-2596 static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne Link Here
2590
	/* Check if the same font is on some other console already */
2661
	/* Check if the same font is on some other console already */
2591
	for (i = first_fb_vc; i <= last_fb_vc; i++) {
2662
	for (i = first_fb_vc; i <= last_fb_vc; i++) {
2592
		struct vc_data *tmp = vc_cons[i].d;
2663
		struct vc_data *tmp = vc_cons[i].d;
2593
		
2664
2594
		if (fb_display[i].userfont &&
2665
		if (fb_display[i].userfont &&
2595
		    fb_display[i].fontdata &&
2666
		    fb_display[i].fontdata &&
2596
		    FNTSUM(fb_display[i].fontdata) == csum &&
2667
		    FNTSUM(fb_display[i].fontdata) == csum &&
Lines 2635-2641 static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) Link Here
2635
	int i, j, k, depth;
2706
	int i, j, k, depth;
2636
	u8 val;
2707
	u8 val;
2637
2708
2638
	if (fbcon_is_inactive(vc, info))
2709
	if (fbcon_is_inactive(vc, info)
2710
#ifdef CONFIG_FB_CON_DECOR
2711
			|| vc->vc_num != fg_console
2712
#endif
2713
		)
2639
		return -EINVAL;
2714
		return -EINVAL;
2640
2715
2641
	if (!CON_IS_VISIBLE(vc))
2716
	if (!CON_IS_VISIBLE(vc))
Lines 2661-2674 static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) Link Here
2661
	} else
2736
	} else
2662
		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2737
		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2663
2738
2664
	return fb_set_cmap(&palette_cmap, info);
2739
	if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2740
	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2741
2742
		u16 *red, *green, *blue;
2743
		int minlen = min(min(info->var.red.length, info->var.green.length),
2744
				     info->var.blue.length);
2745
		int h;
2746
2747
		struct fb_cmap cmap = {
2748
			.start = 0,
2749
			.len = (1 << minlen),
2750
			.red = NULL,
2751
			.green = NULL,
2752
			.blue = NULL,
2753
			.transp = NULL
2754
		};
2755
2756
		red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
2757
2758
		if (!red)
2759
			goto out;
2760
2761
		green = red + 256;
2762
		blue = green + 256;
2763
		cmap.red = red;
2764
		cmap.green = green;
2765
		cmap.blue = blue;
2766
2767
		for (i = 0; i < cmap.len; i++) {
2768
			red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
2769
		}
2770
2771
		h = fb_set_cmap(&cmap, info);
2772
		fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
2773
		kfree(red);
2774
2775
		return h;
2776
2777
	} else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2778
		   info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
2779
		fb_set_cmap(&info->bgdecor.cmap, info);
2780
2781
out:	return fb_set_cmap(&palette_cmap, info);
2665
}
2782
}
2666
2783
2667
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
2784
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
2668
{
2785
{
2669
	unsigned long p;
2786
	unsigned long p;
2670
	int line;
2787
	int line;
2671
	
2788
2672
	if (vc->vc_num != fg_console || !softback_lines)
2789
	if (vc->vc_num != fg_console || !softback_lines)
2673
		return (u16 *) (vc->vc_origin + offset);
2790
		return (u16 *) (vc->vc_origin + offset);
2674
	line = offset / vc->vc_size_row;
2791
	line = offset / vc->vc_size_row;
Lines 2887-2893 static void fbcon_modechanged(struct fb_info *info) Link Here
2887
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3004
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2888
		cols /= vc->vc_font.width;
3005
		cols /= vc->vc_font.width;
2889
		rows /= vc->vc_font.height;
3006
		rows /= vc->vc_font.height;
2890
		vc_resize(vc, cols, rows);
3007
3008
		if (!fbcon_decor_active_nores(info, vc)) {
3009
			vc_resize(vc, cols, rows);
3010
		} else {
3011
			fbcon_decor_disable(vc, 0);
3012
			fbcon_decor_call_helper("modechange", vc->vc_num);
3013
		}
3014
2891
		updatescrollmode(p, info, vc);
3015
		updatescrollmode(p, info, vc);
2892
		scrollback_max = 0;
3016
		scrollback_max = 0;
2893
		scrollback_current = 0;
3017
		scrollback_current = 0;
Lines 2932-2938 static void fbcon_set_all_vcs(struct fb_info *info) Link Here
2932
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3056
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2933
		cols /= vc->vc_font.width;
3057
		cols /= vc->vc_font.width;
2934
		rows /= vc->vc_font.height;
3058
		rows /= vc->vc_font.height;
2935
		vc_resize(vc, cols, rows);
3059
		if (!fbcon_decor_active_nores(info, vc)) {
3060
			vc_resize(vc, cols, rows);
3061
		}
2936
	}
3062
	}
2937
3063
2938
	if (fg != -1)
3064
	if (fg != -1)
Lines 3542-3547 static void fbcon_exit(void) Link Here
3542
		}
3668
		}
3543
	}
3669
	}
3544
3670
3671
	fbcon_decor_exit();
3545
	fbcon_has_exited = 1;
3672
	fbcon_has_exited = 1;
3546
}
3673
}
3547
3674
Lines 3595-3601 static void __exit fb_console_exit(void) Link Here
3595
	fbcon_exit();
3722
	fbcon_exit();
3596
	console_unlock();
3723
	console_unlock();
3597
	unregister_con_driver(&fb_con);
3724
	unregister_con_driver(&fb_con);
3598
}	
3725
}
3599
3726
3600
module_exit(fb_console_exit);
3727
module_exit(fb_console_exit);
3601
3728
(-)a/drivers/video/console/fbcondecor.c (+555 lines)
Line 0 Link Here
1
/*
2
 *  linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations
3
 *
4
 *  Copyright (C) 2004-2009 Michal Januszewski <spock@gentoo.org>
5
 *
6
 *  Code based upon "Bootsplash" (C) 2001-2003
7
 *       Volker Poplawski <volker@poplawski.de>,
8
 *       Stefan Reinauer <stepan@suse.de>,
9
 *       Steffen Winterfeldt <snwint@suse.de>,
10
 *       Michael Schroeder <mls@suse.de>,
11
 *       Ken Wimer <wimer@suse.de>.
12
 *
13
 *  Compat ioctl support by Thorsten Klein <TK@Thorsten-Klein.de>.
14
 *
15
 *  This file is subject to the terms and conditions of the GNU General Public
16
 *  License.  See the file COPYING in the main directory of this archive for
17
 *  more details.
18
 *
19
 */
20
#include <linux/module.h>
21
#include <linux/kernel.h>
22
#include <linux/string.h>
23
#include <linux/types.h>
24
#include <linux/fb.h>
25
#include <linux/vt_kern.h>
26
#include <linux/vmalloc.h>
27
#include <linux/unistd.h>
28
#include <linux/syscalls.h>
29
#include <linux/init.h>
30
#include <linux/proc_fs.h>
31
#include <linux/workqueue.h>
32
#include <linux/kmod.h>
33
#include <linux/miscdevice.h>
34
#include <linux/device.h>
35
#include <linux/fs.h>
36
#include <linux/compat.h>
37
#include <linux/console.h>
38
39
#include <asm/uaccess.h>
40
#include <asm/irq.h>
41
42
#include "fbcon.h"
43
#include "fbcondecor.h"
44
45
extern signed char con2fb_map[];
46
static int fbcon_decor_enable(struct vc_data *vc);
47
char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
48
static int initialized = 0;
49
50
int fbcon_decor_call_helper(char* cmd, unsigned short vc)
51
{
52
	char *envp[] = {
53
		"HOME=/",
54
		"PATH=/sbin:/bin",
55
		NULL
56
	};
57
58
	char tfb[5];
59
	char tcons[5];
60
	unsigned char fb = (int) con2fb_map[vc];
61
62
	char *argv[] = {
63
		fbcon_decor_path,
64
		"2",
65
		cmd,
66
		tcons,
67
		tfb,
68
		vc_cons[vc].d->vc_decor.theme,
69
		NULL
70
	};
71
72
	snprintf(tfb,5,"%d",fb);
73
	snprintf(tcons,5,"%d",vc);
74
75
	return call_usermodehelper(fbcon_decor_path, argv, envp, UMH_WAIT_EXEC);
76
}
77
78
/* Disables fbcondecor on a virtual console; called with console sem held. */
79
int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw)
80
{
81
	struct fb_info* info;
82
83
	if (!vc->vc_decor.state)
84
		return -EINVAL;
85
86
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
87
88
	if (info == NULL)
89
		return -EINVAL;
90
91
	vc->vc_decor.state = 0;
92
	vc_resize(vc, info->var.xres / vc->vc_font.width,
93
		  info->var.yres / vc->vc_font.height);
94
95
	if (fg_console == vc->vc_num && redraw) {
96
		redraw_screen(vc, 0);
97
		update_region(vc, vc->vc_origin +
98
			      vc->vc_size_row * vc->vc_top,
99
			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
100
	}
101
102
	printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n",
103
			 vc->vc_num);
104
105
	return 0;
106
}
107
108
/* Enables fbcondecor on a virtual console; called with console sem held. */
109
static int fbcon_decor_enable(struct vc_data *vc)
110
{
111
	struct fb_info* info;
112
113
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
114
115
	if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 ||
116
	    info == NULL || vc->vc_decor.state || (!info->bgdecor.data &&
117
	    vc->vc_num == fg_console))
118
		return -EINVAL;
119
120
	vc->vc_decor.state = 1;
121
	vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width,
122
		  vc->vc_decor.theight / vc->vc_font.height);
123
124
	if (fg_console == vc->vc_num) {
125
		redraw_screen(vc, 0);
126
		update_region(vc, vc->vc_origin +
127
			      vc->vc_size_row * vc->vc_top,
128
			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
129
		fbcon_decor_clear_margins(vc, info, 0);
130
	}
131
132
	printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n",
133
			 vc->vc_num);
134
135
	return 0;
136
}
137
138
static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin)
139
{
140
	int ret;
141
142
//	if (origin == FBCON_DECOR_IO_ORIG_USER)
143
		console_lock();
144
	if (!state)
145
		ret = fbcon_decor_disable(vc, 1);
146
	else
147
		ret = fbcon_decor_enable(vc);
148
//	if (origin == FBCON_DECOR_IO_ORIG_USER)
149
		console_unlock();
150
151
	return ret;
152
}
153
154
static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state)
155
{
156
	*state = vc->vc_decor.state;
157
}
158
159
static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin)
160
{
161
	struct fb_info *info;
162
	int len;
163
	char *tmp;
164
165
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
166
167
	if (info == NULL || !cfg->twidth || !cfg->theight ||
168
	    cfg->tx + cfg->twidth  > info->var.xres ||
169
	    cfg->ty + cfg->theight > info->var.yres)
170
		return -EINVAL;
171
172
	len = strlen_user(cfg->theme);
173
	if (!len || len > FBCON_DECOR_THEME_LEN)
174
		return -EINVAL;
175
	tmp = kmalloc(len, GFP_KERNEL);
176
	if (!tmp)
177
		return -ENOMEM;
178
	if (copy_from_user(tmp, (void __user *)cfg->theme, len))
179
		return -EFAULT;
180
	cfg->theme = tmp;
181
	cfg->state = 0;
182
183
	/* If this ioctl is a response to a request from kernel, the console sem
184
	 * is already held; we also don't need to disable decor because either the
185
	 * new config and background picture will be successfully loaded, and the
186
	 * decor will stay on, or in case of a failure it'll be turned off in fbcon. */
187
//	if (origin == FBCON_DECOR_IO_ORIG_USER) {
188
		console_lock();
189
		if (vc->vc_decor.state)
190
			fbcon_decor_disable(vc, 1);
191
//	}
192
193
	if (vc->vc_decor.theme)
194
		kfree(vc->vc_decor.theme);
195
196
	vc->vc_decor = *cfg;
197
198
//	if (origin == FBCON_DECOR_IO_ORIG_USER)
199
		console_unlock();
200
201
	printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n",
202
			 vc->vc_num, vc->vc_decor.theme);
203
	return 0;
204
}
205
206
static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc, struct vc_decor *decor)
207
{
208
	char __user *tmp;
209
210
	tmp = decor->theme;
211
	*decor = vc->vc_decor;
212
	decor->theme = tmp;
213
214
	if (vc->vc_decor.theme) {
215
		if (copy_to_user(tmp, vc->vc_decor.theme, strlen(vc->vc_decor.theme) + 1))
216
			return -EFAULT;
217
	} else
218
		if (put_user(0, tmp))
219
			return -EFAULT;
220
221
	return 0;
222
}
223
224
static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img, unsigned char origin)
225
{
226
	struct fb_info *info;
227
	int len;
228
	u8 *tmp;
229
230
	if (vc->vc_num != fg_console)
231
		return -EINVAL;
232
233
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
234
235
	if (info == NULL)
236
		return -EINVAL;
237
238
	if (img->width != info->var.xres || img->height != info->var.yres) {
239
		printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n");
240
		printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height, info->var.xres, info->var.yres);
241
		return -EINVAL;
242
	}
243
244
	if (img->depth != info->var.bits_per_pixel) {
245
		printk(KERN_ERR "fbcondecor: picture depth mismatch\n");
246
		return -EINVAL;
247
	}
248
249
	if (img->depth == 8) {
250
		if (!img->cmap.len || !img->cmap.red || !img->cmap.green ||
251
		    !img->cmap.blue)
252
			return -EINVAL;
253
254
		tmp = vmalloc(img->cmap.len * 3 * 2);
255
		if (!tmp)
256
			return -ENOMEM;
257
258
		if (copy_from_user(tmp,
259
			    	   (void __user*)img->cmap.red, (img->cmap.len << 1)) ||
260
		    copy_from_user(tmp + (img->cmap.len << 1),
261
			    	   (void __user*)img->cmap.green, (img->cmap.len << 1)) ||
262
		    copy_from_user(tmp + (img->cmap.len << 2),
263
			    	   (void __user*)img->cmap.blue, (img->cmap.len << 1))) {
264
			vfree(tmp);
265
			return -EFAULT;
266
		}
267
268
		img->cmap.transp = NULL;
269
		img->cmap.red = (u16*)tmp;
270
		img->cmap.green = img->cmap.red + img->cmap.len;
271
		img->cmap.blue = img->cmap.green + img->cmap.len;
272
	} else {
273
		img->cmap.red = NULL;
274
	}
275
276
	len = ((img->depth + 7) >> 3) * img->width * img->height;
277
278
	/*
279
	 * Allocate an additional byte so that we never go outside of the
280
	 * buffer boundaries in the rendering functions in a 24 bpp mode.
281
	 */
282
	tmp = vmalloc(len + 1);
283
284
	if (!tmp)
285
		goto out;
286
287
	if (copy_from_user(tmp, (void __user*)img->data, len))
288
		goto out;
289
290
	img->data = tmp;
291
292
	/* If this ioctl is a response to a request from kernel, the console sem
293
	 * is already held. */
294
//	if (origin == FBCON_DECOR_IO_ORIG_USER)
295
		console_lock();
296
297
	if (info->bgdecor.data)
298
		vfree((u8*)info->bgdecor.data);
299
	if (info->bgdecor.cmap.red)
300
		vfree(info->bgdecor.cmap.red);
301
302
	info->bgdecor = *img;
303
304
	if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) {
305
		redraw_screen(vc, 0);
306
		update_region(vc, vc->vc_origin +
307
			      vc->vc_size_row * vc->vc_top,
308
			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
309
		fbcon_decor_clear_margins(vc, info, 0);
310
	}
311
312
//	if (origin == FBCON_DECOR_IO_ORIG_USER)
313
		console_unlock();
314
315
	return 0;
316
317
out:	if (img->cmap.red)
318
		vfree(img->cmap.red);
319
320
	if (tmp)
321
		vfree(tmp);
322
	return -ENOMEM;
323
}
324
325
static long fbcon_decor_ioctl(struct file *filp, u_int cmd, u_long arg)
326
{
327
	struct fbcon_decor_iowrapper __user *wrapper = (void __user*) arg;
328
	struct vc_data *vc = NULL;
329
	unsigned short vc_num = 0;
330
	unsigned char origin = 0;
331
	void __user *data = NULL;
332
333
	if (!access_ok(VERIFY_READ, wrapper,
334
			sizeof(struct fbcon_decor_iowrapper)))
335
		return -EFAULT;
336
337
	__get_user(vc_num, &wrapper->vc);
338
	__get_user(origin, &wrapper->origin);
339
	__get_user(data, &wrapper->data);
340
341
	if (!vc_cons_allocated(vc_num))
342
		return -EINVAL;
343
344
	vc = vc_cons[vc_num].d;
345
346
	switch (cmd) {
347
	case FBIOCONDECOR_SETPIC:
348
	{
349
		struct fb_image img;
350
		if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image)))
351
			return -EFAULT;
352
353
		return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
354
	}
355
	case FBIOCONDECOR_SETCFG:
356
	{
357
		struct vc_decor cfg;
358
		if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
359
			return -EFAULT;
360
361
		return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
362
	}
363
	case FBIOCONDECOR_GETCFG:
364
	{
365
		int rval;
366
		struct vc_decor cfg;
367
368
		if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
369
			return -EFAULT;
370
371
		rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
372
373
		if (copy_to_user(data, &cfg, sizeof(struct vc_decor)))
374
			return -EFAULT;
375
		return rval;
376
	}
377
	case FBIOCONDECOR_SETSTATE:
378
	{
379
		unsigned int state = 0;
380
		if (get_user(state, (unsigned int __user *)data))
381
			return -EFAULT;
382
		return fbcon_decor_ioctl_dosetstate(vc, state, origin);
383
	}
384
	case FBIOCONDECOR_GETSTATE:
385
	{
386
		unsigned int state = 0;
387
		fbcon_decor_ioctl_dogetstate(vc, &state);
388
		return put_user(state, (unsigned int __user *)data);
389
	}
390
391
	default:
392
		return -ENOIOCTLCMD;
393
	}
394
}
395
396
#ifdef CONFIG_COMPAT
397
398
static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
399
400
	struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg;
401
	struct vc_data *vc = NULL;
402
	unsigned short vc_num = 0;
403
	unsigned char origin = 0;
404
	compat_uptr_t data_compat = 0;
405
	void __user *data = NULL;
406
407
	if (!access_ok(VERIFY_READ, wrapper,
408
                       sizeof(struct fbcon_decor_iowrapper32)))
409
		return -EFAULT;
410
411
	__get_user(vc_num, &wrapper->vc);
412
	__get_user(origin, &wrapper->origin);
413
	__get_user(data_compat, &wrapper->data);
414
	data = compat_ptr(data_compat);
415
416
	if (!vc_cons_allocated(vc_num))
417
		return -EINVAL;
418
419
	vc = vc_cons[vc_num].d;
420
421
	switch (cmd) {
422
	case FBIOCONDECOR_SETPIC32:
423
	{
424
		struct fb_image32 img_compat;
425
		struct fb_image img;
426
427
		if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32)))
428
			return -EFAULT;
429
430
		fb_image_from_compat(img, img_compat);
431
432
		return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
433
	}
434
435
	case FBIOCONDECOR_SETCFG32:
436
	{
437
		struct vc_decor32 cfg_compat;
438
		struct vc_decor cfg;
439
440
		if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
441
			return -EFAULT;
442
443
		vc_decor_from_compat(cfg, cfg_compat);
444
445
		return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
446
	}
447
448
	case FBIOCONDECOR_GETCFG32:
449
	{
450
		int rval;
451
		struct vc_decor32 cfg_compat;
452
		struct vc_decor cfg;
453
454
		if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
455
			return -EFAULT;
456
		cfg.theme = compat_ptr(cfg_compat.theme);
457
458
		rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
459
460
		vc_decor_to_compat(cfg_compat, cfg);
461
462
		if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32)))
463
			return -EFAULT;
464
		return rval;
465
	}
466
467
	case FBIOCONDECOR_SETSTATE32:
468
	{
469
		compat_uint_t state_compat = 0;
470
		unsigned int state = 0;
471
472
		if (get_user(state_compat, (compat_uint_t __user *)data))
473
			return -EFAULT;
474
475
		state = (unsigned int)state_compat;
476
477
		return fbcon_decor_ioctl_dosetstate(vc, state, origin);
478
	}
479
480
	case FBIOCONDECOR_GETSTATE32:
481
	{
482
		compat_uint_t state_compat = 0;
483
		unsigned int state = 0;
484
485
		fbcon_decor_ioctl_dogetstate(vc, &state);
486
		state_compat = (compat_uint_t)state;
487
488
		return put_user(state_compat, (compat_uint_t __user *)data);
489
	}
490
491
	default:
492
		return -ENOIOCTLCMD;
493
	}
494
}
495
#else
496
  #define fbcon_decor_compat_ioctl NULL
497
#endif
498
499
static struct file_operations fbcon_decor_ops = {
500
	.owner = THIS_MODULE,
501
	.unlocked_ioctl = fbcon_decor_ioctl,
502
	.compat_ioctl = fbcon_decor_compat_ioctl
503
};
504
505
static struct miscdevice fbcon_decor_dev = {
506
	.minor = MISC_DYNAMIC_MINOR,
507
	.name = "fbcondecor",
508
	.fops = &fbcon_decor_ops
509
};
510
511
void fbcon_decor_reset()
512
{
513
	int i;
514
515
	for (i = 0; i < num_registered_fb; i++) {
516
		registered_fb[i]->bgdecor.data = NULL;
517
		registered_fb[i]->bgdecor.cmap.red = NULL;
518
	}
519
520
	for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
521
		vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth =
522
						vc_cons[i].d->vc_decor.theight = 0;
523
		vc_cons[i].d->vc_decor.theme = NULL;
524
	}
525
526
	return;
527
}
528
529
int fbcon_decor_init()
530
{
531
	int i;
532
533
	fbcon_decor_reset();
534
535
	if (initialized)
536
		return 0;
537
538
	i = misc_register(&fbcon_decor_dev);
539
	if (i) {
540
		printk(KERN_ERR "fbcondecor: failed to register device\n");
541
		return i;
542
	}
543
544
	fbcon_decor_call_helper("init", 0);
545
	initialized = 1;
546
	return 0;
547
}
548
549
int fbcon_decor_exit(void)
550
{
551
	fbcon_decor_reset();
552
	return 0;
553
}
554
555
EXPORT_SYMBOL(fbcon_decor_path);
(-)a/drivers/video/console/fbcondecor.h (+78 lines)
Line 0 Link Here
1
/* 
2
 *  linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers
3
 *
4
 *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
5
 *
6
 */
7
8
#ifndef __FBCON_DECOR_H
9
#define __FBCON_DECOR_H
10
11
#ifndef _LINUX_FB_H
12
#include <linux/fb.h>
13
#endif
14
15
/* This is needed for vc_cons in fbcmap.c */
16
#include <linux/vt_kern.h>
17
18
struct fb_cursor;
19
struct fb_info;
20
struct vc_data;
21
22
#ifdef CONFIG_FB_CON_DECOR
23
/* fbcondecor.c */
24
int fbcon_decor_init(void);
25
int fbcon_decor_exit(void);
26
int fbcon_decor_call_helper(char* cmd, unsigned short cons);
27
int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw);
28
29
/* cfbcondecor.c */
30
void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
31
void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor);
32
void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
33
void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
34
void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank);
35
void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
36
void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
37
void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
38
39
/* vt.c */
40
void acquire_console_sem(void);
41
void release_console_sem(void);
42
void do_unblank_screen(int entering_gfx);
43
44
/* struct vc_data *y */
45
#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme) 
46
47
/* struct fb_info *x, struct vc_data *y */
48
#define fbcon_decor_active_nores(x,y) (x->bgdecor.data && fbcon_decor_active_vc(y))
49
50
/* struct fb_info *x, struct vc_data *y */
51
#define fbcon_decor_active(x,y) (fbcon_decor_active_nores(x,y) &&		\
52
			      x->bgdecor.width == x->var.xres && 	\
53
			      x->bgdecor.height == x->var.yres &&	\
54
			      x->bgdecor.depth == x->var.bits_per_pixel)
55
56
57
#else /* CONFIG_FB_CON_DECOR */
58
59
static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
60
static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
61
static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
62
static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
63
static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
64
static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
65
static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
66
static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
67
static inline int fbcon_decor_call_helper(char* cmd, unsigned short cons) { return 0; }
68
static inline int fbcon_decor_init(void) { return 0; }
69
static inline int fbcon_decor_exit(void) { return 0; }
70
static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
71
72
#define fbcon_decor_active_vc(y) (0)
73
#define fbcon_decor_active_nores(x,y) (0)
74
#define fbcon_decor_active(x,y) (0)
75
76
#endif /* CONFIG_FB_CON_DECOR */
77
78
#endif /* __FBCON_DECOR_H */
(-)a/drivers/video/fbcmap.c (-3 / +8 lines)
Lines 17-22 Link Here
17
#include <linux/slab.h>
17
#include <linux/slab.h>
18
#include <linux/uaccess.h>
18
#include <linux/uaccess.h>
19
19
20
#include "console/fbcondecor.h"
21
20
static u16 red2[] __read_mostly = {
22
static u16 red2[] __read_mostly = {
21
    0x0000, 0xaaaa
23
    0x0000, 0xaaaa
22
};
24
};
Lines 249-262 int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) Link Here
249
			if (transp)
251
			if (transp)
250
				htransp = *transp++;
252
				htransp = *transp++;
251
			if (info->fbops->fb_setcolreg(start++,
253
			if (info->fbops->fb_setcolreg(start++,
252
						      hred, hgreen, hblue,
254
						      hred, hgreen, hblue, 
253
						      htransp, info))
255
						      htransp, info))
254
				break;
256
				break;
255
		}
257
		}
256
	}
258
	}
257
	if (rc == 0)
259
	if (rc == 0) {
258
		fb_copy_cmap(cmap, &info->cmap);
260
		fb_copy_cmap(cmap, &info->cmap);
259
261
		if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
262
		    info->fix.visual == FB_VISUAL_DIRECTCOLOR)
263
			fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
264
	}
260
	return rc;
265
	return rc;
261
}
266
}
262
267
(-)a/drivers/video/fbmem.c (-9 lines)
Lines 1222-1236 struct fb_fix_screeninfo32 { Link Here
1222
	u16			reserved[3];
1222
	u16			reserved[3];
1223
};
1223
};
1224
1224
1225
struct fb_cmap32 {
1226
	u32			start;
1227
	u32			len;
1228
	compat_caddr_t	red;
1229
	compat_caddr_t	green;
1230
	compat_caddr_t	blue;
1231
	compat_caddr_t	transp;
1232
};
1233
1234
static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1225
static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1235
			  unsigned long arg)
1226
			  unsigned long arg)
1236
{
1227
{
(-)a/include/linux/console_decor.h (+46 lines)
Line 0 Link Here
1
#ifndef _LINUX_CONSOLE_DECOR_H_
2
#define _LINUX_CONSOLE_DECOR_H_ 1
3
4
/* A structure used by the framebuffer console decorations (drivers/video/console/fbcondecor.c) */
5
struct vc_decor {
6
	__u8 bg_color;				/* The color that is to be treated as transparent */
7
	__u8 state;				/* Current decor state: 0 = off, 1 = on */
8
	__u16 tx, ty;				/* Top left corner coordinates of the text field */
9
	__u16 twidth, theight;			/* Width and height of the text field */
10
	char* theme;
11
};
12
13
#ifdef __KERNEL__
14
#ifdef CONFIG_COMPAT
15
#include <linux/compat.h>
16
17
struct vc_decor32 {
18
	__u8 bg_color;				/* The color that is to be treated as transparent */
19
	__u8 state;				/* Current decor state: 0 = off, 1 = on */
20
	__u16 tx, ty;				/* Top left corner coordinates of the text field */
21
	__u16 twidth, theight;			/* Width and height of the text field */
22
	compat_uptr_t theme;
23
};
24
25
#define vc_decor_from_compat(to, from) \
26
	(to).bg_color = (from).bg_color; \
27
	(to).state    = (from).state; \
28
	(to).tx       = (from).tx; \
29
	(to).ty       = (from).ty; \
30
	(to).twidth   = (from).twidth; \
31
	(to).theight  = (from).theight; \
32
	(to).theme    = compat_ptr((from).theme)
33
34
#define vc_decor_to_compat(to, from) \
35
	(to).bg_color = (from).bg_color; \
36
	(to).state    = (from).state; \
37
	(to).tx       = (from).tx; \
38
	(to).ty       = (from).ty; \
39
	(to).twidth   = (from).twidth; \
40
	(to).theight  = (from).theight; \
41
	(to).theme    = ptr_to_compat((from).theme)
42
43
#endif /* CONFIG_COMPAT */
44
#endif /* __KERNEL__ */
45
46
#endif
(-)a/include/linux/console_struct.h (+3 lines)
Lines 19-24 Link Here
19
struct vt_struct;
19
struct vt_struct;
20
20
21
#define NPAR 16
21
#define NPAR 16
22
#include <linux/console_decor.h>
22
23
23
struct vc_data {
24
struct vc_data {
24
	struct tty_port port;			/* Upper level data */
25
	struct tty_port port;			/* Upper level data */
Lines 107-112 struct vc_data { Link Here
107
	unsigned long	vc_uni_pagedir;
108
	unsigned long	vc_uni_pagedir;
108
	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
109
	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
109
	bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
110
	bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
111
112
	struct vc_decor vc_decor;
110
	/* additional information is in vt_kern.h */
113
	/* additional information is in vt_kern.h */
111
};
114
};
112
115
(-)a/include/uapi/linux/fb.h (+59 lines)
Lines 11-16 Link Here
11
11
12
#define FB_MAX			32	/* sufficient for now */
12
#define FB_MAX			32	/* sufficient for now */
13
13
14
struct fbcon_decor_iowrapper
15
{
16
	unsigned short vc;		/* Virtual console */
17
	unsigned char origin;		/* Point of origin of the request */
18
	void *data;
19
};
20
21
#ifdef __KERNEL__
22
#ifdef CONFIG_COMPAT
23
#include <linux/compat.h>
24
struct fbcon_decor_iowrapper32
25
{
26
	unsigned short vc;		/* Virtual console */
27
	unsigned char origin;		/* Point of origin of the request */
28
	compat_uptr_t data;
29
};
30
#endif /* CONFIG_COMPAT */
31
#endif /* __KERNEL__ */
32
14
/* ioctls
33
/* ioctls
15
   0x46 is 'F'								*/
34
   0x46 is 'F'								*/
16
#define FBIOGET_VSCREENINFO	0x4600
35
#define FBIOGET_VSCREENINFO	0x4600
Lines 39-44 Link Here
39
#define FBIOPUT_MODEINFO        0x4617
58
#define FBIOPUT_MODEINFO        0x4617
40
#define FBIOGET_DISPINFO        0x4618
59
#define FBIOGET_DISPINFO        0x4618
41
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
60
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
61
#define FBIOCONDECOR_SETCFG	_IOWR('F', 0x19, struct fbcon_decor_iowrapper)
62
#define FBIOCONDECOR_GETCFG	_IOR('F', 0x1A, struct fbcon_decor_iowrapper)
63
#define FBIOCONDECOR_SETSTATE	_IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
64
#define FBIOCONDECOR_GETSTATE	_IOR('F', 0x1C, struct fbcon_decor_iowrapper)
65
#define FBIOCONDECOR_SETPIC 	_IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
66
#ifdef __KERNEL__
67
#ifdef CONFIG_COMPAT
68
#define FBIOCONDECOR_SETCFG32	_IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
69
#define FBIOCONDECOR_GETCFG32	_IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
70
#define FBIOCONDECOR_SETSTATE32	_IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
71
#define FBIOCONDECOR_GETSTATE32	_IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
72
#define FBIOCONDECOR_SETPIC32	_IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
73
#endif /* CONFIG_COMPAT */
74
#endif /* __KERNEL__ */
75
76
#define FBCON_DECOR_THEME_LEN		128	/* Maximum lenght of a theme name */
77
#define FBCON_DECOR_IO_ORIG_KERNEL	0	/* Kernel ioctl origin */
78
#define FBCON_DECOR_IO_ORIG_USER	1	/* User ioctl origin */
42
79
43
#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
80
#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
44
#define FB_TYPE_PLANES			1	/* Non interleaved planes */
81
#define FB_TYPE_PLANES			1	/* Non interleaved planes */
Lines 291-296 struct fb_cmap { Link Here
291
	__u16 *transp;			/* transparency, can be NULL */
328
	__u16 *transp;			/* transparency, can be NULL */
292
};
329
};
293
330
331
#ifdef __KERNEL__
332
#ifdef CONFIG_COMPAT
333
struct fb_cmap32 {
334
	__u32 start;
335
	__u32 len;			/* Number of entries */
336
	compat_uptr_t red;		/* Red values	*/
337
	compat_uptr_t green;
338
	compat_uptr_t blue;
339
	compat_uptr_t transp;		/* transparency, can be NULL */
340
};
341
342
#define fb_cmap_from_compat(to, from) \
343
	(to).start  = (from).start; \
344
	(to).len    = (from).len; \
345
	(to).red    = compat_ptr((from).red); \
346
	(to).green  = compat_ptr((from).green); \
347
	(to).blue   = compat_ptr((from).blue); \
348
	(to).transp = compat_ptr((from).transp)
349
350
#endif /* CONFIG_COMPAT */
351
#endif /* __KERNEL__ */
352
294
struct fb_con2fbmap {
353
struct fb_con2fbmap {
295
	__u32 console;
354
	__u32 console;
296
	__u32 framebuffer;
355
	__u32 framebuffer;
(-)a/include/linux/fb.h (+31 lines)
Lines 372-377 struct fb_image { Link Here
372
	struct fb_cmap cmap;	/* color map info */
431
	struct fb_cmap cmap;	/* color map info */
373
};
432
};
374
433
434
#ifdef __KERNEL__
435
#ifdef CONFIG_COMPAT
436
struct fb_image32 {
437
	__u32 dx;			/* Where to place image */
438
	__u32 dy;
439
	__u32 width;			/* Size of image */
440
	__u32 height;
441
	__u32 fg_color;			/* Only used when a mono bitmap */
442
	__u32 bg_color;
443
	__u8  depth;			/* Depth of the image */
444
	const compat_uptr_t data;	/* Pointer to image data */
445
	struct fb_cmap32 cmap;		/* color map info */
446
};
447
448
#define fb_image_from_compat(to, from) \
449
	(to).dx       = (from).dx; \
450
	(to).dy       = (from).dy; \
451
	(to).width    = (from).width; \
452
	(to).height   = (from).height; \
453
	(to).fg_color = (from).fg_color; \
454
	(to).bg_color = (from).bg_color; \
455
	(to).depth    = (from).depth; \
456
	(to).data     = compat_ptr((from).data); \
457
	fb_cmap_from_compat((to).cmap, (from).cmap)
458
459
#endif /* CONFIG_COMPAT */
460
#endif /* __KERNEL__ */
461
375
/*
462
/*
376
 * hardware cursor control
463
 * hardware cursor control
377
 */
464
 */
Lines 881-886 struct fb_info { Link Here
881
#define FBINFO_STATE_SUSPENDED	1
968
#define FBINFO_STATE_SUSPENDED	1
882
	u32 state;			/* Hardware state i.e suspend */
969
	u32 state;			/* Hardware state i.e suspend */
883
	void *fbcon_par;                /* fbcon use-only private area */
970
	void *fbcon_par;                /* fbcon use-only private area */
971
972
	struct fb_image bgdecor;
973
884
	/* From here on everything is device dependent */
974
	/* From here on everything is device dependent */
885
	void *par;
975
	void *par;
886
	/* we need the PCI or similar aperture base/size not
976
	/* we need the PCI or similar aperture base/size not
(-)a/kernel/sysctl.c (-11 / +23 lines)
Lines 142-147 static int min_percpu_pagelist_fract = 8; Link Here
142
static int ngroups_max = NGROUPS_MAX;
142
static int ngroups_max = NGROUPS_MAX;
143
static const int cap_last_cap = CAP_LAST_CAP;
143
static const int cap_last_cap = CAP_LAST_CAP;
144
144
145
#ifdef CONFIG_FB_CON_DECOR
146
extern char fbcon_decor_path[];
147
#endif
148
145
#ifdef CONFIG_INOTIFY_USER
149
#ifdef CONFIG_INOTIFY_USER
146
#include <linux/inotify.h>
150
#include <linux/inotify.h>
147
#endif
151
#endif
Lines 238-243 static struct ctl_table sysctl_base_table[] = { Link Here
238
		.mode		= 0555,
242
		.mode		= 0555,
239
		.child		= dev_table,
243
		.child		= dev_table,
240
	},
244
	},
245
#ifdef CONFIG_FB_CON_DECOR
246
	{
247
		.procname	= "fbcondecor",
248
		.data		= &fbcon_decor_path,
249
		.maxlen		= KMOD_PATH_LEN,
250
		.mode		= 0644,
251
		.proc_handler	= &proc_dostring,
252
	},
253
#endif
241
	{ }
254
	{ }
242
};
255
};
243
256
Lines 1038-1044 static struct ctl_table vm_table[] = { Link Here
1038
		.proc_handler	= proc_dointvec,
1051
		.proc_handler	= proc_dointvec,
1039
	},
1052
	},
1040
	{
1053
	{
1041
		.procname	= "page-cluster", 
1054
		.procname	= "page-cluster",
1042
		.data		= &page_cluster,
1055
		.data		= &page_cluster,
1043
		.maxlen		= sizeof(int),
1056
		.maxlen		= sizeof(int),
1044
		.mode		= 0644,
1057
		.mode		= 0644,
Lines 1484-1490 static struct ctl_table fs_table[] = { Link Here
1484
		.mode		= 0555,
1497
		.mode		= 0555,
1485
		.child		= inotify_table,
1498
		.child		= inotify_table,
1486
	},
1499
	},
1487
#endif	
1500
#endif
1488
#ifdef CONFIG_EPOLL
1501
#ifdef CONFIG_EPOLL
1489
	{
1502
	{
1490
		.procname	= "epoll",
1503
		.procname	= "epoll",
Lines 1802-1813 static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, Link Here
1802
	unsigned long page = 0;
1815
	unsigned long page = 0;
1803
	size_t left;
1816
	size_t left;
1804
	char *kbuf;
1817
	char *kbuf;
1805
	
1818
1806
	if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
1819
	if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
1807
		*lenp = 0;
1820
		*lenp = 0;
1808
		return 0;
1821
		return 0;
1809
	}
1822
	}
1810
	
1823
1811
	i = (int *) tbl_data;
1824
	i = (int *) tbl_data;
1812
	vleft = table->maxlen / sizeof(*i);
1825
	vleft = table->maxlen / sizeof(*i);
1813
	left = *lenp;
1826
	left = *lenp;
Lines 1896-1902 static int do_proc_dointvec(struct ctl_table *table, int write, Link Here
1896
 * @ppos: file position
1909
 * @ppos: file position
1897
 *
1910
 *
1898
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1911
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1899
 * values from/to the user buffer, treated as an ASCII string. 
1912
 * values from/to the user buffer, treated as an ASCII string.
1900
 *
1913
 *
1901
 * Returns 0 on success.
1914
 * Returns 0 on success.
1902
 */
1915
 */
Lines 2223-2229 static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lvalp, Link Here
2223
 * @ppos: file position
2236
 * @ppos: file position
2224
 *
2237
 *
2225
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2238
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2226
 * values from/to the user buffer, treated as an ASCII string. 
2239
 * values from/to the user buffer, treated as an ASCII string.
2227
 * The values read are assumed to be in seconds, and are converted into
2240
 * The values read are assumed to be in seconds, and are converted into
2228
 * jiffies.
2241
 * jiffies.
2229
 *
2242
 *
Lines 2245-2252 int proc_dointvec_jiffies(struct ctl_table *table, int write, Link Here
2245
 * @ppos: pointer to the file position
2258
 * @ppos: pointer to the file position
2246
 *
2259
 *
2247
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2260
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2248
 * values from/to the user buffer, treated as an ASCII string. 
2261
 * values from/to the user buffer, treated as an ASCII string.
2249
 * The values read are assumed to be in 1/USER_HZ seconds, and 
2262
 * The values read are assumed to be in 1/USER_HZ seconds, and
2250
 * are converted into jiffies.
2263
 * are converted into jiffies.
2251
 *
2264
 *
2252
 * Returns 0 on success.
2265
 * Returns 0 on success.
Lines 2268-2275 int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, Link Here
2268
 * @ppos: the current position in the file
2281
 * @ppos: the current position in the file
2269
 *
2282
 *
2270
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2283
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2271
 * values from/to the user buffer, treated as an ASCII string. 
2284
 * values from/to the user buffer, treated as an ASCII string.
2272
 * The values read are assumed to be in 1/1000 seconds, and 
2285
 * The values read are assumed to be in 1/1000 seconds, and
2273
 * are converted into jiffies.
2286
 * are converted into jiffies.
2274
 *
2287
 *
2275
 * Returns 0 on success.
2288
 * Returns 0 on success.
2276
- 

Return to bug 452574