Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 459060 | 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 16-19 obj-$(CONFIG_PCI) += pci/ Link Here
16
obj-$(CONFIG_PARISC)		+= parisc/
16
obj-$(CONFIG_PARISC)		+= parisc/
17
obj-$(CONFIG_RAPIDIO)		+= rapidio/
17
obj-$(CONFIG_RAPIDIO)		+= rapidio/
18
# tty/ comes before char/ so that the VT console is the boot-time
19
# default.
20
obj-y				+= tty/
21
obj-y				+= char/
18
obj-y				+= video/
22
obj-y				+= video/
19
obj-y				+= idle/
23
obj-y				+= idle/
Lines 37-47 obj-$(CONFIG_XEN) += xen/ Link Here
37
# regulators early, since some subsystems rely on them to initialize
41
# regulators early, since some subsystems rely on them to initialize
38
obj-$(CONFIG_REGULATOR)		+= regulator/
42
obj-$(CONFIG_REGULATOR)		+= regulator/
39
43
40
# tty/ comes before char/ so that the VT console is the boot-time
41
# default.
42
obj-y				+= tty/
43
obj-y				+= char/
44
45
# gpu/ comes after char for AGP vs DRM startup
44
# gpu/ comes after char for AGP vs DRM startup
46
obj-y				+= gpu/
45
obj-y				+= gpu/
47
46
(-)a/drivers/video/Kconfig (-1 lines)
Lines 1229-1235 config FB_MATROX Link Here
1229
	select FB_CFB_FILLRECT
1229
	select FB_CFB_FILLRECT
1230
	select FB_CFB_COPYAREA
1230
	select FB_CFB_COPYAREA
1231
	select FB_CFB_IMAGEBLIT
1231
	select FB_CFB_IMAGEBLIT
1232
	select FB_TILEBLITTING
1233
	select FB_MACMODES if PPC_PMAC
1232
	select FB_MACMODES if PPC_PMAC
1234
	---help---
1233
	---help---
1235
	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
1234
	  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 465-471 static int __init fb_console_setup(char *this_opt) Link Here
465
			} else
466
			} else
466
				return 1;
467
				return 1;
467
		}
468
		}
468
		
469
469
		if (!strncmp(options, "map:", 4)) {
470
		if (!strncmp(options, "map:", 4)) {
470
			options += 4;
471
			options += 4;
471
			if (*options) {
472
			if (*options) {
Lines 490-497 static int __init fb_console_setup(char *this_opt) Link Here
490
				first_fb_vc = 0;
491
				first_fb_vc = 0;
491
			if (*options++ == '-')
492
			if (*options++ == '-')
492
				last_fb_vc = simple_strtoul(options, &options, 10) - 1;
493
				last_fb_vc = simple_strtoul(options, &options, 10) - 1;
493
			fbcon_is_default = 0; 
494
			fbcon_is_default = 0;
494
		}	
495
		}
495
496
496
		if (!strncmp(options, "rotate:", 7)) {
497
		if (!strncmp(options, "rotate:", 7)) {
497
			options += 7;
498
			options += 7;
Lines 552-557 static int fbcon_takeover(int show_logo) Link Here
552
		info_idx = -1;
553
		info_idx = -1;
553
	} else {
554
	} else {
554
		fbcon_has_console_bind = 1;
555
		fbcon_has_console_bind = 1;
556
#ifdef CONFIG_FB_CON_DECOR
557
		fbcon_decor_init();
558
#endif
555
	}
559
	}
556
560
557
	return err;
561
	return err;
Lines 942-948 static const char *fbcon_startup(void) Link Here
942
	info = registered_fb[info_idx];
946
	info = registered_fb[info_idx];
943
	if (!info)
947
	if (!info)
944
		return NULL;
948
		return NULL;
945
	
949
946
	owner = info->fbops->owner;
950
	owner = info->fbops->owner;
947
	if (!try_module_get(owner))
951
	if (!try_module_get(owner))
948
		return NULL;
952
		return NULL;
Lines 1006-1011 static const char *fbcon_startup(void) Link Here
1006
	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1010
	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1007
	cols /= vc->vc_font.width;
1011
	cols /= vc->vc_font.width;
1008
	rows /= vc->vc_font.height;
1012
	rows /= vc->vc_font.height;
1013
1014
	if (fbcon_decor_active(info, vc)) {
1015
		cols = vc->vc_decor.twidth / vc->vc_font.width;
1016
		rows = vc->vc_decor.theight / vc->vc_font.height;
1017
	}
1018
1009
	vc_resize(vc, cols, rows);
1019
	vc_resize(vc, cols, rows);
1010
1020
1011
	DPRINTK("mode:   %s\n", info->fix.id);
1021
	DPRINTK("mode:   %s\n", info->fix.id);
Lines 1035-1041 static void fbcon_init(struct vc_data *vc, int init) Link Here
1035
	cap = info->flags;
1045
	cap = info->flags;
1036
1046
1037
	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1047
	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1038
	    (info->fix.type == FB_TYPE_TEXT))
1048
	    (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
1039
		logo = 0;
1049
		logo = 0;
1040
1050
1041
	if (var_to_display(p, &info->var, info))
1051
	if (var_to_display(p, &info->var, info))
Lines 1245-1250 static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, Link Here
1245
	if (sy < vc->vc_top && vc->vc_top == logo_lines)
1255
	if (sy < vc->vc_top && vc->vc_top == logo_lines)
1246
		vc->vc_top = 0;
1256
		vc->vc_top = 0;
1247
1257
1258
 	if (fbcon_decor_active(info, vc)) {
1259
 		fbcon_decor_clear(vc, info, sy, sx, height, width);
1260
 		return;
1261
 	}
1262
1248
	/* Split blits that cross physical y_wrap boundary */
1263
	/* Split blits that cross physical y_wrap boundary */
1249
1264
1250
	y_break = p->vrows - p->yscroll;
1265
	y_break = p->vrows - p->yscroll;
Lines 1264-1273 static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, Link Here
1264
	struct display *p = &fb_display[vc->vc_num];
1279
	struct display *p = &fb_display[vc->vc_num];
1265
	struct fbcon_ops *ops = info->fbcon_par;
1280
	struct fbcon_ops *ops = info->fbcon_par;
1266
1281
1267
	if (!fbcon_is_inactive(vc, info))
1282
	if (!fbcon_is_inactive(vc, info)) {
1268
		ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1283
1269
			   get_color(vc, info, scr_readw(s), 1),
1284
		if (fbcon_decor_active(info, vc))
1270
			   get_color(vc, info, scr_readw(s), 0));
1285
			fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
1286
		else
1287
			ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1288
				   get_color(vc, info, scr_readw(s), 1),
1289
				   get_color(vc, info, scr_readw(s), 0));
1290
	}
1271
}
1291
}
1272
1292
1273
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
1293
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
Lines 1283-1290 static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) Link Here
1283
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1303
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1284
	struct fbcon_ops *ops = info->fbcon_par;
1304
	struct fbcon_ops *ops = info->fbcon_par;
1285
1305
1286
	if (!fbcon_is_inactive(vc, info))
1306
	if (!fbcon_is_inactive(vc, info)) {
1287
		ops->clear_margins(vc, info, bottom_only);
1307
	 	if (fbcon_decor_active(info, vc)) {
1308
	 		fbcon_decor_clear_margins(vc, info, bottom_only);
1309
 		} else {
1310
			ops->clear_margins(vc, info, bottom_only);
1311
		}
1312
	}
1288
}
1313
}
1289
1314
1290
static void fbcon_cursor(struct vc_data *vc, int mode)
1315
static void fbcon_cursor(struct vc_data *vc, int mode)
Lines 1394-1400 static __inline__ void ywrap_up(struct vc_data *vc, int count) Link Here
1394
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1419
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1395
	struct fbcon_ops *ops = info->fbcon_par;
1420
	struct fbcon_ops *ops = info->fbcon_par;
1396
	struct display *p = &fb_display[vc->vc_num];
1421
	struct display *p = &fb_display[vc->vc_num];
1397
	
1422
1398
	p->yscroll += count;
1423
	p->yscroll += count;
1399
	if (p->yscroll >= p->vrows)	/* Deal with wrap */
1424
	if (p->yscroll >= p->vrows)	/* Deal with wrap */
1400
		p->yscroll -= p->vrows;
1425
		p->yscroll -= p->vrows;
Lines 1413-1419 static __inline__ void ywrap_down(struct vc_data *vc, int count) Link Here
1413
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1438
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1414
	struct fbcon_ops *ops = info->fbcon_par;
1439
	struct fbcon_ops *ops = info->fbcon_par;
1415
	struct display *p = &fb_display[vc->vc_num];
1440
	struct display *p = &fb_display[vc->vc_num];
1416
	
1441
1417
	p->yscroll -= count;
1442
	p->yscroll -= count;
1418
	if (p->yscroll < 0)	/* Deal with wrap */
1443
	if (p->yscroll < 0)	/* Deal with wrap */
1419
		p->yscroll += p->vrows;
1444
		p->yscroll += p->vrows;
Lines 1480-1486 static __inline__ void ypan_down(struct vc_data *vc, int count) Link Here
1480
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1505
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1481
	struct display *p = &fb_display[vc->vc_num];
1506
	struct display *p = &fb_display[vc->vc_num];
1482
	struct fbcon_ops *ops = info->fbcon_par;
1507
	struct fbcon_ops *ops = info->fbcon_par;
1483
	
1508
1484
	p->yscroll -= count;
1509
	p->yscroll -= count;
1485
	if (p->yscroll < 0) {
1510
	if (p->yscroll < 0) {
1486
		ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
1511
		ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
Lines 1804-1810 static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, Link Here
1804
			count = vc->vc_rows;
1829
			count = vc->vc_rows;
1805
		if (softback_top)
1830
		if (softback_top)
1806
			fbcon_softback_note(vc, t, count);
1831
			fbcon_softback_note(vc, t, count);
1807
		if (logo_shown >= 0)
1832
		if (logo_shown >= 0 || fbcon_decor_active(info, vc))
1808
			goto redraw_up;
1833
			goto redraw_up;
1809
		switch (p->scrollmode) {
1834
		switch (p->scrollmode) {
1810
		case SCROLL_MOVE:
1835
		case SCROLL_MOVE:
Lines 1897-1902 static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, Link Here
1897
			count = vc->vc_rows;
1922
			count = vc->vc_rows;
1898
		if (logo_shown >= 0)
1923
		if (logo_shown >= 0)
1899
			goto redraw_down;
1924
			goto redraw_down;
1925
		if (fbcon_decor_active(info, vc))
1926
			goto redraw_down;
1900
		switch (p->scrollmode) {
1927
		switch (p->scrollmode) {
1901
		case SCROLL_MOVE:
1928
		case SCROLL_MOVE:
1902
			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
1929
			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
Lines 1989-1995 static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, Link Here
1989
{
2016
{
1990
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2017
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1991
	struct display *p = &fb_display[vc->vc_num];
2018
	struct display *p = &fb_display[vc->vc_num];
1992
	
2019
1993
	if (fbcon_is_inactive(vc, info))
2020
	if (fbcon_is_inactive(vc, info))
1994
		return;
2021
		return;
1995
2022
Lines 2007-2013 static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, Link Here
2007
			p->vrows - p->yscroll);
2034
			p->vrows - p->yscroll);
2008
}
2035
}
2009
2036
2010
static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, 
2037
static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,
2011
			    int dy, int dx, int height, int width, u_int y_break)
2038
			    int dy, int dx, int height, int width, u_int y_break)
2012
{
2039
{
2013
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2040
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
Lines 2045-2050 static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s Link Here
2045
		}
2072
		}
2046
		return;
2073
		return;
2047
	}
2074
	}
2075
2076
	if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
2077
 		/* must use slower redraw bmove to keep background pic intact */
2078
 		fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
2079
 		return;
2080
 	}
2081
2048
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2082
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2049
		   height, width);
2083
		   height, width);
2050
}
2084
}
Lines 2096-2102 static void updatescrollmode(struct display *p, Link Here
2096
	}
2130
	}
2097
}
2131
}
2098
2132
2099
static int fbcon_resize(struct vc_data *vc, unsigned int width, 
2133
static int fbcon_resize(struct vc_data *vc, unsigned int width,
2100
			unsigned int height, unsigned int user)
2134
			unsigned int height, unsigned int user)
2101
{
2135
{
2102
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2136
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
Lines 2115-2122 static int fbcon_resize(struct vc_data *vc, unsigned int width, Link Here
2115
	var.yres = virt_h * virt_fh;
2149
	var.yres = virt_h * virt_fh;
2116
	x_diff = info->var.xres - var.xres;
2150
	x_diff = info->var.xres - var.xres;
2117
	y_diff = info->var.yres - var.yres;
2151
	y_diff = info->var.yres - var.yres;
2118
	if (x_diff < 0 || x_diff > virt_fw ||
2152
	if ((x_diff < 0 || x_diff > virt_fw ||
2119
	    y_diff < 0 || y_diff > virt_fh) {
2153
		y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
2120
		const struct fb_videomode *mode;
2154
		const struct fb_videomode *mode;
2121
2155
2122
		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
2156
		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
Lines 2152-2157 static int fbcon_switch(struct vc_data *vc) Link Here
2152
2186
2153
	info = registered_fb[con2fb_map[vc->vc_num]];
2187
	info = registered_fb[con2fb_map[vc->vc_num]];
2154
	ops = info->fbcon_par;
2188
	ops = info->fbcon_par;
2189
	prev_console = ops->currcon;
2190
	if (prev_console != -1)
2191
		old_info = registered_fb[con2fb_map[prev_console]];
2192
2193
#ifdef CONFIG_FB_CON_DECOR
2194
	if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2195
		struct vc_data *vc_curr = vc_cons[prev_console].d;
2196
		if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
2197
			/* Clear the screen to avoid displaying funky colors during
2198
			 * palette updates. */
2199
			memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset,
2200
			       0, info->var.yres * info->fix.line_length);
2201
		}
2202
	}
2203
#endif
2155
2204
2156
	if (softback_top) {
2205
	if (softback_top) {
2157
		if (softback_lines)
2206
		if (softback_lines)
Lines 2170-2178 static int fbcon_switch(struct vc_data *vc) Link Here
2170
		logo_shown = FBCON_LOGO_CANSHOW;
2219
		logo_shown = FBCON_LOGO_CANSHOW;
2171
	}
2220
	}
2172
2221
2173
	prev_console = ops->currcon;
2174
	if (prev_console != -1)
2175
		old_info = registered_fb[con2fb_map[prev_console]];
2176
	/*
2222
	/*
2177
	 * FIXME: If we have multiple fbdev's loaded, we need to
2223
	 * FIXME: If we have multiple fbdev's loaded, we need to
2178
	 * update all info->currcon.  Perhaps, we can place this
2224
	 * update all info->currcon.  Perhaps, we can place this
Lines 2216-2221 static int fbcon_switch(struct vc_data *vc) Link Here
2216
			fbcon_del_cursor_timer(old_info);
2262
			fbcon_del_cursor_timer(old_info);
2217
	}
2263
	}
2218
2264
2265
	if (fbcon_decor_active_vc(vc)) {
2266
		struct vc_data *vc_curr = vc_cons[prev_console].d;
2267
2268
		if (!vc_curr->vc_decor.theme ||
2269
			strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
2270
			(fbcon_decor_active_nores(info, vc_curr) &&
2271
			 !fbcon_decor_active(info, vc_curr))) {
2272
			fbcon_decor_disable(vc, 0);
2273
			fbcon_decor_call_helper("modechange", vc->vc_num);
2274
		}
2275
	}
2276
2219
	if (fbcon_is_inactive(vc, info) ||
2277
	if (fbcon_is_inactive(vc, info) ||
2220
	    ops->blank_state != FB_BLANK_UNBLANK)
2278
	    ops->blank_state != FB_BLANK_UNBLANK)
2221
		fbcon_del_cursor_timer(info);
2279
		fbcon_del_cursor_timer(info);
Lines 2264-2274 static int fbcon_switch(struct vc_data *vc) Link Here
2264
	    ops->update_start(info);
2322
	    ops->update_start(info);
2265
	}
2323
	}
2266
2324
2267
	fbcon_set_palette(vc, color_table); 	
2325
	fbcon_set_palette(vc, color_table);
2268
	fbcon_clear_margins(vc, 0);
2326
	fbcon_clear_margins(vc, 0);
2269
2327
2270
	if (logo_shown == FBCON_LOGO_DRAW) {
2328
	if (logo_shown == FBCON_LOGO_DRAW) {
2271
2272
		logo_shown = fg_console;
2329
		logo_shown = fg_console;
2273
		/* This is protected above by initmem_freed */
2330
		/* This is protected above by initmem_freed */
2274
		fb_show_logo(info, ops->rotate);
2331
		fb_show_logo(info, ops->rotate);
Lines 2324-2338 static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) Link Here
2324
		}
2381
		}
2325
	}
2382
	}
2326
2383
2327
 	if (!fbcon_is_inactive(vc, info)) {
2384
	if (!fbcon_is_inactive(vc, info)) {
2328
		if (ops->blank_state != blank) {
2385
		if (ops->blank_state != blank) {
2329
			ops->blank_state = blank;
2386
			ops->blank_state = blank;
2330
			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2387
			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2331
			ops->cursor_flash = (!blank);
2388
			ops->cursor_flash = (!blank);
2332
2389
2333
			if (!(info->flags & FBINFO_MISC_USEREVENT))
2390
			if (!(info->flags & FBINFO_MISC_USEREVENT)) {
2334
				if (fb_blank(info, blank))
2391
				if (fb_blank(info, blank)) {
2335
					fbcon_generic_blank(vc, info, blank);
2392
					if (fbcon_decor_active(info, vc))
2393
						fbcon_decor_blank(vc, info, blank);
2394
					else
2395
						fbcon_generic_blank(vc, info, blank);
2396
				}
2397
			}
2336
		}
2398
		}
2337
2399
2338
		if (!blank)
2400
		if (!blank)
Lines 2454-2460 static int fbcon_do_set_font(struct vc_data *vc, int w, int h, Link Here
2454
			vc->vc_complement_mask >>= 1;
2516
			vc->vc_complement_mask >>= 1;
2455
			vc->vc_s_complement_mask >>= 1;
2517
			vc->vc_s_complement_mask >>= 1;
2456
		}
2518
		}
2457
			
2519
2458
		/* ++Edmund: reorder the attribute bits */
2520
		/* ++Edmund: reorder the attribute bits */
2459
		if (vc->vc_can_do_color) {
2521
		if (vc->vc_can_do_color) {
2460
			unsigned short *cp =
2522
			unsigned short *cp =
Lines 2477-2483 static int fbcon_do_set_font(struct vc_data *vc, int w, int h, Link Here
2477
			vc->vc_complement_mask <<= 1;
2539
			vc->vc_complement_mask <<= 1;
2478
			vc->vc_s_complement_mask <<= 1;
2540
			vc->vc_s_complement_mask <<= 1;
2479
		}
2541
		}
2480
			
2542
2481
		/* ++Edmund: reorder the attribute bits */
2543
		/* ++Edmund: reorder the attribute bits */
2482
		{
2544
		{
2483
			unsigned short *cp =
2545
			unsigned short *cp =
Lines 2507-2519 static int fbcon_do_set_font(struct vc_data *vc, int w, int h, Link Here
2507
	}
2569
	}
2508
2570
2509
	if (resize) {
2571
	if (resize) {
2572
		/* reset wrap/pan */
2510
		int cols, rows;
2573
		int cols, rows;
2511
2574
2512
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2575
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2513
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2576
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2577
2578
		if (fbcon_decor_active(info, vc)) {
2579
			info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2580
			cols = vc->vc_decor.twidth;
2581
			rows = vc->vc_decor.theight;
2582
		}
2514
		cols /= w;
2583
		cols /= w;
2515
		rows /= h;
2584
		rows /= h;
2585
2516
		vc_resize(vc, cols, rows);
2586
		vc_resize(vc, cols, rows);
2587
2517
		if (CON_IS_VISIBLE(vc) && softback_buf)
2588
		if (CON_IS_VISIBLE(vc) && softback_buf)
2518
			fbcon_update_softback(vc);
2589
			fbcon_update_softback(vc);
2519
	} else if (CON_IS_VISIBLE(vc)
2590
	} else if (CON_IS_VISIBLE(vc)
Lines 2597-2603 static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne Link Here
2597
	/* Check if the same font is on some other console already */
2661
	/* Check if the same font is on some other console already */
2598
	for (i = first_fb_vc; i <= last_fb_vc; i++) {
2662
	for (i = first_fb_vc; i <= last_fb_vc; i++) {
2599
		struct vc_data *tmp = vc_cons[i].d;
2663
		struct vc_data *tmp = vc_cons[i].d;
2600
		
2664
2601
		if (fb_display[i].userfont &&
2665
		if (fb_display[i].userfont &&
2602
		    fb_display[i].fontdata &&
2666
		    fb_display[i].fontdata &&
2603
		    FNTSUM(fb_display[i].fontdata) == csum &&
2667
		    FNTSUM(fb_display[i].fontdata) == csum &&
Lines 2642-2648 static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) Link Here
2642
	int i, j, k, depth;
2713
	int i, j, k, depth;
2643
	u8 val;
2714
	u8 val;
2644
2715
2645
	if (fbcon_is_inactive(vc, info))
2716
	if (fbcon_is_inactive(vc, info)
2717
#ifdef CONFIG_FB_CON_DECOR
2718
			|| vc->vc_num != fg_console
2719
#endif
2720
		)
2646
		return -EINVAL;
2721
		return -EINVAL;
2647
2722
2648
	if (!CON_IS_VISIBLE(vc))
2723
	if (!CON_IS_VISIBLE(vc))
Lines 2668-2681 static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) Link Here
2668
	} else
2743
	} else
2669
		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2744
		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2670
2745
2671
	return fb_set_cmap(&palette_cmap, info);
2746
	if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2747
	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2748
2749
		u16 *red, *green, *blue;
2750
		int minlen = min(min(info->var.red.length, info->var.green.length),
2751
				     info->var.blue.length);
2752
		int h;
2753
2754
		struct fb_cmap cmap = {
2755
			.start = 0,
2756
			.len = (1 << minlen),
2757
			.red = NULL,
2758
			.green = NULL,
2759
			.blue = NULL,
2760
			.transp = NULL
2761
		};
2762
2763
		red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
2764
2765
		if (!red)
2766
			goto out;
2767
2768
		green = red + 256;
2769
		blue = green + 256;
2770
		cmap.red = red;
2771
		cmap.green = green;
2772
		cmap.blue = blue;
2773
2774
		for (i = 0; i < cmap.len; i++) {
2775
			red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
2776
		}
2777
2778
		h = fb_set_cmap(&cmap, info);
2779
		fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
2780
		kfree(red);
2781
2782
		return h;
2783
2784
	} else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2785
		   info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
2786
		fb_set_cmap(&info->bgdecor.cmap, info);
2787
2788
out:	return fb_set_cmap(&palette_cmap, info);
2672
}
2789
}
2673
2790
2674
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
2791
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
2675
{
2792
{
2676
	unsigned long p;
2793
	unsigned long p;
2677
	int line;
2794
	int line;
2678
	
2795
2679
	if (vc->vc_num != fg_console || !softback_lines)
2796
	if (vc->vc_num != fg_console || !softback_lines)
2680
		return (u16 *) (vc->vc_origin + offset);
2797
		return (u16 *) (vc->vc_origin + offset);
2681
	line = offset / vc->vc_size_row;
2798
	line = offset / vc->vc_size_row;
Lines 2894-2900 static void fbcon_modechanged(struct fb_info *info) Link Here
2894
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3011
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2895
		cols /= vc->vc_font.width;
3012
		cols /= vc->vc_font.width;
2896
		rows /= vc->vc_font.height;
3013
		rows /= vc->vc_font.height;
2897
		vc_resize(vc, cols, rows);
3014
3015
		if (!fbcon_decor_active_nores(info, vc)) {
3016
			vc_resize(vc, cols, rows);
3017
		} else {
3018
			fbcon_decor_disable(vc, 0);
3019
			fbcon_decor_call_helper("modechange", vc->vc_num);
3020
		}
3021
2898
		updatescrollmode(p, info, vc);
3022
		updatescrollmode(p, info, vc);
2899
		scrollback_max = 0;
3023
		scrollback_max = 0;
2900
		scrollback_current = 0;
3024
		scrollback_current = 0;
Lines 2939-2945 static void fbcon_set_all_vcs(struct fb_info *info) Link Here
2939
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3063
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2940
		cols /= vc->vc_font.width;
3064
		cols /= vc->vc_font.width;
2941
		rows /= vc->vc_font.height;
3065
		rows /= vc->vc_font.height;
2942
		vc_resize(vc, cols, rows);
3066
		if (!fbcon_decor_active_nores(info, vc)) {
3067
			vc_resize(vc, cols, rows);
3068
		}
2943
	}
3069
	}
2944
3070
2945
	if (fg != -1)
3071
	if (fg != -1)
Lines 3549-3554 static void fbcon_exit(void) Link Here
3549
		}
3675
		}
3550
	}
3676
	}
3551
3677
3678
	fbcon_decor_exit();
3552
	fbcon_has_exited = 1;
3679
	fbcon_has_exited = 1;
3553
}
3680
}
3554
3681
Lines 3602-3608 static void __exit fb_console_exit(void) Link Here
3602
	fbcon_exit();
3729
	fbcon_exit();
3603
	console_unlock();
3730
	console_unlock();
3604
	unregister_con_driver(&fb_con);
3731
	unregister_con_driver(&fb_con);
3605
}	
3732
}
3606
3733
3607
module_exit(fb_console_exit);
3734
module_exit(fb_console_exit);
3608
3735
(-)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 1231-1245 struct fb_fix_screeninfo32 { Link Here
1231
	u16			reserved[3];
1231
	u16			reserved[3];
1232
};
1232
};
1233
1233
1234
struct fb_cmap32 {
1235
	u32			start;
1236
	u32			len;
1237
	compat_caddr_t	red;
1238
	compat_caddr_t	green;
1239
	compat_caddr_t	blue;
1240
	compat_caddr_t	transp;
1241
};
1242
1243
static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1234
static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1244
			  unsigned long arg)
1235
			  unsigned long arg)
1245
{
1236
{
(-)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 (+87 lines)
Lines 8-13 Link Here
8
8
9
#define FB_MAX			32	/* sufficient for now */
9
#define FB_MAX			32	/* sufficient for now */
10
10
11
struct fbcon_decor_iowrapper
12
{
13
	unsigned short vc;		/* Virtual console */
14
	unsigned char origin;		/* Point of origin of the request */
15
	void *data;
16
};
17
18
#ifdef __KERNEL__
19
#ifdef CONFIG_COMPAT
20
#include <linux/compat.h>
21
struct fbcon_decor_iowrapper32
22
{
23
	unsigned short vc;		/* Virtual console */
24
	unsigned char origin;		/* Point of origin of the request */
25
	compat_uptr_t data;
26
};
27
#endif /* CONFIG_COMPAT */
28
#endif /* __KERNEL__ */
29
11
/* ioctls
30
/* ioctls
12
   0x46 is 'F'								*/
31
   0x46 is 'F'								*/
13
#define FBIOGET_VSCREENINFO	0x4600
32
#define FBIOGET_VSCREENINFO	0x4600
Lines 34-39 Link Here
34
#define FBIOPUT_MODEINFO        0x4617
53
#define FBIOPUT_MODEINFO        0x4617
35
#define FBIOGET_DISPINFO        0x4618
54
#define FBIOGET_DISPINFO        0x4618
36
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
55
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
56
#define FBIOCONDECOR_SETCFG	_IOWR('F', 0x19, struct fbcon_decor_iowrapper)
57
#define FBIOCONDECOR_GETCFG	_IOR('F', 0x1A, struct fbcon_decor_iowrapper)
58
#define FBIOCONDECOR_SETSTATE	_IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
59
#define FBIOCONDECOR_GETSTATE	_IOR('F', 0x1C, struct fbcon_decor_iowrapper)
60
#define FBIOCONDECOR_SETPIC 	_IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
61
#ifdef __KERNEL__
62
#ifdef CONFIG_COMPAT
63
#define FBIOCONDECOR_SETCFG32	_IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
64
#define FBIOCONDECOR_GETCFG32	_IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
65
#define FBIOCONDECOR_SETSTATE32	_IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
66
#define FBIOCONDECOR_GETSTATE32	_IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
67
#define FBIOCONDECOR_SETPIC32	_IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
68
#endif /* CONFIG_COMPAT */
69
#endif /* __KERNEL__ */
70
71
#define FBCON_DECOR_THEME_LEN		128	/* Maximum lenght of a theme name */
72
#define FBCON_DECOR_IO_ORIG_KERNEL	0	/* Kernel ioctl origin */
73
#define FBCON_DECOR_IO_ORIG_USER	1	/* User ioctl origin */
37
74
38
#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
75
#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
39
#define FB_TYPE_PLANES			1	/* Non interleaved planes */
76
#define FB_TYPE_PLANES			1	/* Non interleaved planes */
Lines 286-291 struct fb_cmap { Link Here
286
	__u16 *transp;			/* transparency, can be NULL */
323
	__u16 *transp;			/* transparency, can be NULL */
287
};
324
};
288
325
326
#ifdef __KERNEL__
327
#ifdef CONFIG_COMPAT
328
struct fb_cmap32 {
329
	__u32 start;
330
	__u32 len;			/* Number of entries */
331
	compat_uptr_t red;		/* Red values	*/
332
	compat_uptr_t green;
333
	compat_uptr_t blue;
334
	compat_uptr_t transp;		/* transparency, can be NULL */
335
};
336
337
#define fb_cmap_from_compat(to, from) \
338
	(to).start  = (from).start; \
339
	(to).len    = (from).len; \
340
	(to).red    = compat_ptr((from).red); \
341
	(to).green  = compat_ptr((from).green); \
342
	(to).blue   = compat_ptr((from).blue); \
343
	(to).transp = compat_ptr((from).transp)
344
345
#endif /* CONFIG_COMPAT */
346
#endif /* __KERNEL__ */
347
289
struct fb_con2fbmap {
348
struct fb_con2fbmap {
290
	__u32 console;
349
	__u32 console;
291
	__u32 framebuffer;
350
	__u32 framebuffer;
Lines 367-372 struct fb_image { Link Here
367
	struct fb_cmap cmap;	/* color map info */
426
	struct fb_cmap cmap;	/* color map info */
368
};
427
};
369
428
429
#ifdef __KERNEL__
430
#ifdef CONFIG_COMPAT
431
struct fb_image32 {
432
	__u32 dx;			/* Where to place image */
433
	__u32 dy;
434
	__u32 width;			/* Size of image */
435
	__u32 height;
436
	__u32 fg_color;			/* Only used when a mono bitmap */
437
	__u32 bg_color;
438
	__u8  depth;			/* Depth of the image */
439
	const compat_uptr_t data;	/* Pointer to image data */
440
	struct fb_cmap32 cmap;		/* color map info */
441
};
442
443
#define fb_image_from_compat(to, from) \
444
	(to).dx       = (from).dx; \
445
	(to).dy       = (from).dy; \
446
	(to).width    = (from).width; \
447
	(to).height   = (from).height; \
448
	(to).fg_color = (from).fg_color; \
449
	(to).bg_color = (from).bg_color; \
450
	(to).depth    = (from).depth; \
451
	(to).data     = compat_ptr((from).data); \
452
	fb_cmap_from_compat((to).cmap, (from).cmap)
453
454
#endif /* CONFIG_COMPAT */
455
#endif /* __KERNEL__ */
456
370
/*
457
/*
371
 * hardware cursor control
458
 * hardware cursor control
372
 */
459
 */
(-)a/include/linux/fb.h (+3 lines)
Lines 488-492 #define FBINFO_STATE_SUSPENDED 1 Link Here
488
	u32 state;			/* Hardware state i.e suspend */
488
	u32 state;			/* Hardware state i.e suspend */
489
	void *fbcon_par;                /* fbcon use-only private area */
489
	void *fbcon_par;                /* fbcon use-only private area */
490
491
	struct fb_image bgdecor;
492
490
	/* From here on everything is device dependent */
493
	/* From here on everything is device dependent */
491
	void *par;
494
	void *par;
492
	/* we need the PCI or similar aperture base/size not
495
	/* we need the PCI or similar aperture base/size not
(-)a/kernel/sysctl.c (-11 / +23 lines)
Lines 145-150 static int min_percpu_pagelist_fract = 8; Link Here
145
static int ngroups_max = NGROUPS_MAX;
145
static int ngroups_max = NGROUPS_MAX;
146
static const int cap_last_cap = CAP_LAST_CAP;
146
static const int cap_last_cap = CAP_LAST_CAP;
147
147
148
#ifdef CONFIG_FB_CON_DECOR
149
extern char fbcon_decor_path[];
150
#endif
151
148
#ifdef CONFIG_INOTIFY_USER
152
#ifdef CONFIG_INOTIFY_USER
149
#include <linux/inotify.h>
153
#include <linux/inotify.h>
150
#endif
154
#endif
Lines 248-253 static struct ctl_table sysctl_base_table[] = { Link Here
248
		.mode		= 0555,
252
		.mode		= 0555,
249
		.child		= dev_table,
253
		.child		= dev_table,
250
	},
254
	},
255
#ifdef CONFIG_FB_CON_DECOR
256
	{
257
		.procname	= "fbcondecor",
258
		.data		= &fbcon_decor_path,
259
		.maxlen		= KMOD_PATH_LEN,
260
		.mode		= 0644,
261
		.proc_handler	= &proc_dostring,
262
	},
263
#endif
251
	{ }
264
	{ }
252
};
265
};
253
266
Lines 1091-1097 static struct ctl_table vm_table[] = { Link Here
1091
		.proc_handler	= proc_dointvec,
1104
		.proc_handler	= proc_dointvec,
1092
	},
1105
	},
1093
	{
1106
	{
1094
		.procname	= "page-cluster", 
1107
		.procname	= "page-cluster",
1095
		.data		= &page_cluster,
1108
		.data		= &page_cluster,
1096
		.maxlen		= sizeof(int),
1109
		.maxlen		= sizeof(int),
1097
		.mode		= 0644,
1110
		.mode		= 0644,
Lines 1535-1541 static struct ctl_table fs_table[] = { Link Here
1535
		.mode		= 0555,
1548
		.mode		= 0555,
1536
		.child		= inotify_table,
1549
		.child		= inotify_table,
1537
	},
1550
	},
1538
#endif	
1551
#endif
1539
#ifdef CONFIG_EPOLL
1552
#ifdef CONFIG_EPOLL
1540
	{
1553
	{
1541
		.procname	= "epoll",
1554
		.procname	= "epoll",
Lines 1873-1884 static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, Link Here
1873
	unsigned long page = 0;
1886
	unsigned long page = 0;
1874
	size_t left;
1887
	size_t left;
1875
	char *kbuf;
1888
	char *kbuf;
1876
	
1889
1877
	if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
1890
	if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
1878
		*lenp = 0;
1891
		*lenp = 0;
1879
		return 0;
1892
		return 0;
1880
	}
1893
	}
1881
	
1894
1882
	i = (int *) tbl_data;
1895
	i = (int *) tbl_data;
1883
	vleft = table->maxlen / sizeof(*i);
1896
	vleft = table->maxlen / sizeof(*i);
1884
	left = *lenp;
1897
	left = *lenp;
Lines 1967-1973 static int do_proc_dointvec(struct ctl_table *table, int write, Link Here
1967
 * @ppos: file position
1980
 * @ppos: file position
1968
 *
1981
 *
1969
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1982
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1970
 * values from/to the user buffer, treated as an ASCII string. 
1983
 * values from/to the user buffer, treated as an ASCII string.
1971
 *
1984
 *
1972
 * Returns 0 on success.
1985
 * Returns 0 on success.
1973
 */
1986
 */
Lines 2326-2332 static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lvalp, Link Here
2326
 * @ppos: file position
2339
 * @ppos: file position
2327
 *
2340
 *
2328
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2341
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2329
 * values from/to the user buffer, treated as an ASCII string. 
2342
 * values from/to the user buffer, treated as an ASCII string.
2330
 * The values read are assumed to be in seconds, and are converted into
2343
 * The values read are assumed to be in seconds, and are converted into
2331
 * jiffies.
2344
 * jiffies.
2332
 *
2345
 *
Lines 2348-2355 int proc_dointvec_jiffies(struct ctl_table *table, int write, Link Here
2348
 * @ppos: pointer to the file position
2361
 * @ppos: pointer to the file position
2349
 *
2362
 *
2350
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2363
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2351
 * values from/to the user buffer, treated as an ASCII string. 
2364
 * values from/to the user buffer, treated as an ASCII string.
2352
 * The values read are assumed to be in 1/USER_HZ seconds, and 
2365
 * The values read are assumed to be in 1/USER_HZ seconds, and
2353
 * are converted into jiffies.
2366
 * are converted into jiffies.
2354
 *
2367
 *
2355
 * Returns 0 on success.
2368
 * Returns 0 on success.
Lines 2371-2378 int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, Link Here
2371
 * @ppos: the current position in the file
2384
 * @ppos: the current position in the file
2372
 *
2385
 *
2373
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2386
 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2374
 * values from/to the user buffer, treated as an ASCII string. 
2387
 * values from/to the user buffer, treated as an ASCII string.
2375
 * The values read are assumed to be in 1/1000 seconds, and 
2388
 * The values read are assumed to be in 1/1000 seconds, and
2376
 * are converted into jiffies.
2389
 * are converted into jiffies.
2377
 *
2390
 *
2378
 * Returns 0 on success.
2391
 * Returns 0 on success.
2379
- 

Return to bug 459060