Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 629860
Collapse All | Expand All

(-)a/Documentation/fb/00-INDEX (+2 lines)
Lines 23-28 ep93xx-fb.txt Link Here
23
	- info on the driver for EP93xx LCD controller.
23
	- info on the driver for EP93xx LCD controller.
24
fbcon.txt
24
fbcon.txt
25
	- intro to and usage guide for the framebuffer console (fbcon).
25
	- intro to and usage guide for the framebuffer console (fbcon).
26
fbcondecor.txt
27
	- info on the Framebuffer Console Decoration
26
framebuffer.txt
28
framebuffer.txt
27
	- introduction to frame buffer devices.
29
	- introduction to frame buffer devices.
28
gxfb.txt
30
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://github.com/alanhaggai/fbsplash
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 <michalj+fbcondecor@gmail.com>
207
(-)a/drivers/Makefile (-5 / +4 lines)
Lines 17-22 obj-y += pwm/ Link Here
17
obj-$(CONFIG_PCI)		+= pci/
17
obj-$(CONFIG_PCI)		+= pci/
18
obj-$(CONFIG_PARISC)		+= parisc/
18
obj-$(CONFIG_PARISC)		+= parisc/
19
obj-$(CONFIG_RAPIDIO)		+= rapidio/
19
obj-$(CONFIG_RAPIDIO)		+= rapidio/
20
# tty/ comes before char/ so that the VT console is the boot-time
21
# default.
22
obj-y				+= tty/
23
obj-y				+= char/
20
obj-y				+= video/
24
obj-y				+= video/
21
obj-y				+= idle/
25
obj-y				+= idle/
22
26
Lines 45-55 obj-$(CONFIG_REGULATOR) += regulator/ Link Here
45
# reset controllers early, since gpu drivers might rely on them to initialize
49
# reset controllers early, since gpu drivers might rely on them to initialize
46
obj-$(CONFIG_RESET_CONTROLLER)	+= reset/
50
obj-$(CONFIG_RESET_CONTROLLER)	+= reset/
47
51
48
# tty/ comes before char/ so that the VT console is the boot-time
49
# default.
50
obj-y				+= tty/
51
obj-y				+= char/
52
53
# iommu/ comes before gpu as gpu are using iommu controllers
52
# iommu/ comes before gpu as gpu are using iommu controllers
54
obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
53
obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
55
54
(-)a/drivers/video/console/Kconfig (+13 lines)
Lines 130-135 config FRAMEBUFFER_CONSOLE_ROTATION Link Here
130
         such that other users of the framebuffer will remain normally
130
         such that other users of the framebuffer will remain normally
131
         oriented.
131
         oriented.
132
132
133
config FB_CON_DECOR
134
	bool "Support for the Framebuffer Console Decorations"
135
	depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
136
	default n
137
	---help---
138
	  This option enables support for framebuffer console decorations which
139
	  makes it possible to display images in the background of the system
140
	  consoles.  Note that userspace utilities are necessary in order to take
141
	  advantage of these features. Refer to Documentation/fb/fbcondecor.txt
142
	  for more information.
143
144
	  If unsure, say N.
145
133
config STI_CONSOLE
146
config STI_CONSOLE
134
        bool "STI text console"
147
        bool "STI text console"
135
        depends on PARISC
148
        depends on PARISC
(-)a/drivers/video/console/Makefile (+1 lines)
Lines 16-19 obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \ Link Here
16
                                         fbcon_ccw.o
16
                                         fbcon_ccw.o
17
endif
17
endif
18
18
19
obj-$(CONFIG_FB_CON_DECOR)     	  += fbcondecor.o cfbcondecor.o
19
obj-$(CONFIG_FB_STI)              += sticore.o
20
obj-$(CONFIG_FB_STI)              += sticore.o
(-)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 379-389 static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, Link Here
379
	cursor.image.depth = 1;
387
	cursor.image.depth = 1;
380
	cursor.rop = ROP_XOR;
388
	cursor.rop = ROP_XOR;
381
389
382
	if (info->fbops->fb_cursor)
390
	if (fbcon_decor_active(info, vc)) {
383
		err = info->fbops->fb_cursor(info, &cursor);
391
		fbcon_decor_cursor(info, &cursor);
392
	} else {
393
		if (info->fbops->fb_cursor)
394
			err = info->fbops->fb_cursor(info, &cursor);
384
395
385
	if (err)
396
		if (err)
386
		soft_cursor(info, &cursor);
397
			soft_cursor(info, &cursor);
398
	}
387
399
388
	ops->cursor_reset = 0;
400
	ops->cursor_reset = 0;
389
}
401
}
(-)a/drivers/video/console/cfbcondecor.c (+473 lines)
Line 0 Link Here
1
/*
2
 *  linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions
3
 *
4
 *  Copyright (C) 2004 Michal Januszewski <michalj+fbcondecor@gmail.com>
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
			break;
283
		case 16:
284
			for (i = 0; i < width/4; i++) {
285
				fb_writel(bgx, p); p += 4;
286
				fb_writel(bgx, p); p += 4;
287
			}
288
			if (width & 2) {
289
				fb_writel(bgx, p); p += 4;
290
			}
291
			if (width & 1)
292
				fb_writew(bgx, (u16 *)p);
293
			break;
294
		case 8:
295
			for (i = 0; i < width/4; i++) {
296
				fb_writel(bgx, p); p += 4;
297
			}
298
299
			if (width & 2) {
300
				fb_writew(bgx, p); p += 2;
301
			}
302
			if (width & 1)
303
				fb_writeb(bgx, (u8 *)p);
304
			break;
305
306
		}
307
		dst += dstbytes;
308
	}
309
}
310
311
void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
312
		   int srclinebytes, int bpp)
313
{
314
	int i;
315
316
	while (height-- > 0) {
317
		u32 *p = (u32 *)dst;
318
		u32 *q = (u32 *)src;
319
320
		switch (bpp) {
321
322
		case 32:
323
			for (i = 0; i < width; i++)
324
				fb_writel(*q++, p++);
325
			break;
326
		case 24:
327
			for (i = 0; i < (width * 3 / 4); i++)
328
				fb_writel(*q++, p++);
329
			if ((width * 3) % 4) {
330
				if (width & 2) {
331
					fb_writeb(*(u8 *)q, (u8 *)p);
332
				} else if (width & 1) {
333
					fb_writew(*(u16 *)q, (u16 *)p);
334
					fb_writeb(*(u8 *)((u16 *)q + 1),
335
							(u8 *)((u16 *)p + 2));
336
				}
337
			}
338
			break;
339
		case 16:
340
			for (i = 0; i < width/4; i++) {
341
				fb_writel(*q++, p++);
342
				fb_writel(*q++, p++);
343
			}
344
			if (width & 2)
345
				fb_writel(*q++, p++);
346
			if (width & 1)
347
				fb_writew(*(u16 *)q, (u16 *)p);
348
			break;
349
		case 8:
350
			for (i = 0; i < width/4; i++)
351
				fb_writel(*q++, p++);
352
353
			if (width & 2) {
354
				fb_writew(*(u16 *)q, (u16 *)p);
355
				q = (u32 *) ((u16 *)q + 1);
356
				p = (u32 *) ((u16 *)p + 1);
357
			}
358
			if (width & 1)
359
				fb_writeb(*(u8 *)q, (u8 *)p);
360
			break;
361
		}
362
363
		dst += linebytes;
364
		src += srclinebytes;
365
	}
366
}
367
368
static void decorfill(struct fb_info *info, int sy, int sx, int height,
369
		       int width)
370
{
371
	int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
372
	int d  = sy * info->fix.line_length + sx * bytespp;
373
	int ds = (sy * info->var.xres + sx) * bytespp;
374
375
	fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds),
376
		    height, width, info->fix.line_length, info->var.xres * bytespp,
377
		    info->var.bits_per_pixel);
378
}
379
380
void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
381
		    int height, int width)
382
{
383
	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
384
	struct fbcon_ops *ops = info->fbcon_par;
385
	u8 *dst;
386
	int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info);
387
388
	transparent = (vc->vc_decor.bg_color == bg_color);
389
	sy = sy * vc->vc_font.height + vc->vc_decor.ty;
390
	sx = sx * vc->vc_font.width + vc->vc_decor.tx;
391
	height *= vc->vc_font.height;
392
	width *= vc->vc_font.width;
393
394
	/* Don't paint the background image if console is blanked */
395
	if (transparent && !ops->blank_state) {
396
		decorfill(info, sy, sx, height, width);
397
	} else {
398
		dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
399
			     sx * ((info->var.bits_per_pixel + 7) >> 3));
400
		decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
401
			  info->var.bits_per_pixel);
402
	}
403
}
404
405
void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info,
406
			    int bottom_only)
407
{
408
	unsigned int tw = vc->vc_cols*vc->vc_font.width;
409
	unsigned int th = vc->vc_rows*vc->vc_font.height;
410
411
	if (!bottom_only) {
412
		/* top margin */
413
		decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres);
414
		/* left margin */
415
		decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx);
416
		/* right margin */
417
		decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th,
418
			   info->var.xres - vc->vc_decor.tx - tw);
419
	}
420
	decorfill(info, vc->vc_decor.ty + th, 0,
421
		   info->var.yres - vc->vc_decor.ty - th, info->var.xres);
422
}
423
424
void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y,
425
			   int sx, int dx, int width)
426
{
427
	u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
428
	u16 *s = d + (dx - sx);
429
	u16 *start = d;
430
	u16 *ls = d;
431
	u16 *le = d + width;
432
	u16 c;
433
	int x = dx;
434
	u16 attr = 1;
435
436
	do {
437
		c = scr_readw(d);
438
		if (attr != (c & 0xff00)) {
439
			attr = c & 0xff00;
440
			if (d > start) {
441
				fbcon_decor_putcs(vc, info, start, d - start, y, x);
442
				x += d - start;
443
				start = d;
444
			}
445
		}
446
		if (s >= ls && s < le && c == scr_readw(s)) {
447
			if (d > start) {
448
				fbcon_decor_putcs(vc, info, start, d - start, y, x);
449
				x += d - start + 1;
450
				start = d + 1;
451
			} else {
452
				x++;
453
				start++;
454
			}
455
		}
456
		s++;
457
		d++;
458
	} while (d < le);
459
	if (d > start)
460
		fbcon_decor_putcs(vc, info, start, d - start, y, x);
461
}
462
463
void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank)
464
{
465
	if (blank) {
466
		decorset((u8 *)info->screen_base, info->var.yres, info->var.xres,
467
			  info->fix.line_length, 0, info->var.bits_per_pixel);
468
	} else {
469
		update_screen(vc);
470
		fbcon_decor_clear_margins(vc, info, 0);
471
	}
472
}
473
(-)a/drivers/video/console/fbcon.c (-23 / +148 lines)
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 "../console/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 282-288 static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) Link Here
282
		!vt_force_oops_output(vc);
283
		!vt_force_oops_output(vc);
283
}
284
}
284
285
285
static int get_color(struct vc_data *vc, struct fb_info *info,
286
int get_color(struct vc_data *vc, struct fb_info *info,
286
	      u16 c, int is_fg)
287
	      u16 c, int is_fg)
287
{
288
{
288
	int depth = fb_get_color_depth(&info->var, &info->fix);
289
	int depth = fb_get_color_depth(&info->var, &info->fix);
Lines 546-551 static int do_fbcon_takeover(int show_logo) Link Here
546
		info_idx = -1;
547
		info_idx = -1;
547
	} else {
548
	} else {
548
		fbcon_has_console_bind = 1;
549
		fbcon_has_console_bind = 1;
550
#ifdef CONFIG_FB_CON_DECOR
551
		fbcon_decor_init();
552
#endif
549
	}
553
	}
550
554
551
	return err;
555
	return err;
Lines 1005-1010 static const char *fbcon_startup(void) Link Here
1005
	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1009
	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1006
	cols /= vc->vc_font.width;
1010
	cols /= vc->vc_font.width;
1007
	rows /= vc->vc_font.height;
1011
	rows /= vc->vc_font.height;
1012
1013
	if (fbcon_decor_active(info, vc)) {
1014
		cols = vc->vc_decor.twidth / vc->vc_font.width;
1015
		rows = vc->vc_decor.theight / vc->vc_font.height;
1016
	}
1017
1008
	vc_resize(vc, cols, rows);
1018
	vc_resize(vc, cols, rows);
1009
1019
1010
	DPRINTK("mode:   %s\n", info->fix.id);
1020
	DPRINTK("mode:   %s\n", info->fix.id);
Lines 1034-1040 static void fbcon_init(struct vc_data *vc, int init) Link Here
1034
	cap = info->flags;
1044
	cap = info->flags;
1035
1045
1036
	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1046
	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1037
	    (info->fix.type == FB_TYPE_TEXT))
1047
	    (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
1038
		logo = 0;
1048
		logo = 0;
1039
1049
1040
	if (var_to_display(p, &info->var, info))
1050
	if (var_to_display(p, &info->var, info))
Lines 1259-1264 static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, Link Here
1259
		fbcon_clear_margins(vc, 0);
1269
		fbcon_clear_margins(vc, 0);
1260
	}
1270
	}
1261
1271
1272
	if (fbcon_decor_active(info, vc)) {
1273
		fbcon_decor_clear(vc, info, sy, sx, height, width);
1274
		return;
1275
	}
1276
1262
	/* Split blits that cross physical y_wrap boundary */
1277
	/* Split blits that cross physical y_wrap boundary */
1263
1278
1264
	y_break = p->vrows - p->yscroll;
1279
	y_break = p->vrows - p->yscroll;
Lines 1278-1287 static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, Link Here
1278
	struct display *p = &fb_display[vc->vc_num];
1293
	struct display *p = &fb_display[vc->vc_num];
1279
	struct fbcon_ops *ops = info->fbcon_par;
1294
	struct fbcon_ops *ops = info->fbcon_par;
1280
1295
1281
	if (!fbcon_is_inactive(vc, info))
1296
	if (!fbcon_is_inactive(vc, info)) {
1282
		ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1297
1283
			   get_color(vc, info, scr_readw(s), 1),
1298
		if (fbcon_decor_active(info, vc))
1284
			   get_color(vc, info, scr_readw(s), 0));
1299
			fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
1300
		else
1301
			ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1302
				   get_color(vc, info, scr_readw(s), 1),
1303
				   get_color(vc, info, scr_readw(s), 0));
1304
	}
1285
}
1305
}
1286
1306
1287
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
1307
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
Lines 1297-1304 static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) Link Here
1297
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1317
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1298
	struct fbcon_ops *ops = info->fbcon_par;
1318
	struct fbcon_ops *ops = info->fbcon_par;
1299
1319
1300
	if (!fbcon_is_inactive(vc, info))
1320
	if (!fbcon_is_inactive(vc, info)) {
1301
		ops->clear_margins(vc, info, bottom_only);
1321
		if (fbcon_decor_active(info, vc))
1322
			fbcon_decor_clear_margins(vc, info, bottom_only);
1323
		else
1324
			ops->clear_margins(vc, info, bottom_only);
1325
	}
1302
}
1326
}
1303
1327
1304
static void fbcon_cursor(struct vc_data *vc, int mode)
1328
static void fbcon_cursor(struct vc_data *vc, int mode)
Lines 1819-1825 static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, Link Here
1819
			count = vc->vc_rows;
1843
			count = vc->vc_rows;
1820
		if (softback_top)
1844
		if (softback_top)
1821
			fbcon_softback_note(vc, t, count);
1845
			fbcon_softback_note(vc, t, count);
1822
		if (logo_shown >= 0)
1846
		if (logo_shown >= 0 || fbcon_decor_active(info, vc))
1823
			goto redraw_up;
1847
			goto redraw_up;
1824
		switch (p->scrollmode) {
1848
		switch (p->scrollmode) {
1825
		case SCROLL_MOVE:
1849
		case SCROLL_MOVE:
Lines 1912-1917 static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, Link Here
1912
			count = vc->vc_rows;
1936
			count = vc->vc_rows;
1913
		if (logo_shown >= 0)
1937
		if (logo_shown >= 0)
1914
			goto redraw_down;
1938
			goto redraw_down;
1939
		if (fbcon_decor_active(info, vc))
1940
			goto redraw_down;
1915
		switch (p->scrollmode) {
1941
		switch (p->scrollmode) {
1916
		case SCROLL_MOVE:
1942
		case SCROLL_MOVE:
1917
			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
1943
			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
Lines 2060-2065 static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s Link Here
2060
		}
2086
		}
2061
		return;
2087
		return;
2062
	}
2088
	}
2089
2090
	if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
2091
		/* must use slower redraw bmove to keep background pic intact */
2092
		fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
2093
		return;
2094
	}
2095
2063
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2096
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2064
		   height, width);
2097
		   height, width);
2065
}
2098
}
Lines 2130-2137 static int fbcon_resize(struct vc_data *vc, unsigned int width, Link Here
2130
	var.yres = virt_h * virt_fh;
2163
	var.yres = virt_h * virt_fh;
2131
	x_diff = info->var.xres - var.xres;
2164
	x_diff = info->var.xres - var.xres;
2132
	y_diff = info->var.yres - var.yres;
2165
	y_diff = info->var.yres - var.yres;
2133
	if (x_diff < 0 || x_diff > virt_fw ||
2166
	if ((x_diff < 0 || x_diff > virt_fw ||
2134
	    y_diff < 0 || y_diff > virt_fh) {
2167
		y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
2135
		const struct fb_videomode *mode;
2168
		const struct fb_videomode *mode;
2136
2169
2137
		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
2170
		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
Lines 2167-2172 static int fbcon_switch(struct vc_data *vc) Link Here
2167
2200
2168
	info = registered_fb[con2fb_map[vc->vc_num]];
2201
	info = registered_fb[con2fb_map[vc->vc_num]];
2169
	ops = info->fbcon_par;
2202
	ops = info->fbcon_par;
2203
	prev_console = ops->currcon;
2204
	if (prev_console != -1)
2205
		old_info = registered_fb[con2fb_map[prev_console]];
2206
2207
#ifdef CONFIG_FB_CON_DECOR
2208
	if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2209
		struct vc_data *vc_curr = vc_cons[prev_console].d;
2210
2211
		if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
2212
			// Clear the screen to avoid displaying funky colors
2213
			// during palette updates.
2214
			memset((u8 *)info->screen_base + info->fix.line_length * info->var.yoffset,
2215
			       0, info->var.yres * info->fix.line_length);
2216
		}
2217
	}
2218
#endif
2170
2219
2171
	if (softback_top) {
2220
	if (softback_top) {
2172
		if (softback_lines)
2221
		if (softback_lines)
Lines 2185-2193 static int fbcon_switch(struct vc_data *vc) Link Here
2185
		logo_shown = FBCON_LOGO_CANSHOW;
2234
		logo_shown = FBCON_LOGO_CANSHOW;
2186
	}
2235
	}
2187
2236
2188
	prev_console = ops->currcon;
2189
	if (prev_console != -1)
2190
		old_info = registered_fb[con2fb_map[prev_console]];
2191
	/*
2237
	/*
2192
	 * FIXME: If we have multiple fbdev's loaded, we need to
2238
	 * FIXME: If we have multiple fbdev's loaded, we need to
2193
	 * update all info->currcon.  Perhaps, we can place this
2239
	 * update all info->currcon.  Perhaps, we can place this
Lines 2231-2236 static int fbcon_switch(struct vc_data *vc) Link Here
2231
			fbcon_del_cursor_timer(old_info);
2277
			fbcon_del_cursor_timer(old_info);
2232
	}
2278
	}
2233
2279
2280
	if (fbcon_decor_active_vc(vc)) {
2281
		struct vc_data *vc_curr = vc_cons[prev_console].d;
2282
2283
		if (!vc_curr->vc_decor.theme ||
2284
			strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
2285
			(fbcon_decor_active_nores(info, vc_curr) &&
2286
			 !fbcon_decor_active(info, vc_curr))) {
2287
			fbcon_decor_disable(vc, 0);
2288
			fbcon_decor_call_helper("modechange", vc->vc_num);
2289
		}
2290
	}
2291
2234
	if (fbcon_is_inactive(vc, info) ||
2292
	if (fbcon_is_inactive(vc, info) ||
2235
	    ops->blank_state != FB_BLANK_UNBLANK)
2293
	    ops->blank_state != FB_BLANK_UNBLANK)
2236
		fbcon_del_cursor_timer(info);
2294
		fbcon_del_cursor_timer(info);
Lines 2339-2353 static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) Link Here
2339
		}
2397
		}
2340
	}
2398
	}
2341
2399
2342
 	if (!fbcon_is_inactive(vc, info)) {
2400
	if (!fbcon_is_inactive(vc, info)) {
2343
		if (ops->blank_state != blank) {
2401
		if (ops->blank_state != blank) {
2344
			ops->blank_state = blank;
2402
			ops->blank_state = blank;
2345
			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2403
			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2346
			ops->cursor_flash = (!blank);
2404
			ops->cursor_flash = (!blank);
2347
2405
2348
			if (!(info->flags & FBINFO_MISC_USEREVENT))
2406
			if (!(info->flags & FBINFO_MISC_USEREVENT)) {
2349
				if (fb_blank(info, blank))
2407
				if (fb_blank(info, blank)) {
2350
					fbcon_generic_blank(vc, info, blank);
2408
					if (fbcon_decor_active(info, vc))
2409
						fbcon_decor_blank(vc, info, blank);
2410
					else
2411
						fbcon_generic_blank(vc, info, blank);
2412
				}
2413
			}
2351
		}
2414
		}
2352
2415
2353
		if (!blank)
2416
		if (!blank)
Lines 2522-2534 static int fbcon_do_set_font(struct vc_data *vc, int w, int h, Link Here
2522
	}
2585
	}
2523
2586
2524
	if (resize) {
2587
	if (resize) {
2588
		/* reset wrap/pan */
2525
		int cols, rows;
2589
		int cols, rows;
2526
2590
2527
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2591
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2528
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2592
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2593
2594
		if (fbcon_decor_active(info, vc)) {
2595
			info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2596
			cols = vc->vc_decor.twidth;
2597
			rows = vc->vc_decor.theight;
2598
		}
2529
		cols /= w;
2599
		cols /= w;
2530
		rows /= h;
2600
		rows /= h;
2601
2531
		vc_resize(vc, cols, rows);
2602
		vc_resize(vc, cols, rows);
2603
2532
		if (con_is_visible(vc) && softback_buf)
2604
		if (con_is_visible(vc) && softback_buf)
2533
			fbcon_update_softback(vc);
2605
			fbcon_update_softback(vc);
2534
	} else if (con_is_visible(vc)
2606
	} else if (con_is_visible(vc)
Lines 2657-2663 static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table) Link Here
2657
	int i, j, k, depth;
2729
	int i, j, k, depth;
2658
	u8 val;
2730
	u8 val;
2659
2731
2660
	if (fbcon_is_inactive(vc, info))
2732
	if (fbcon_is_inactive(vc, info)
2733
#ifdef CONFIG_FB_CON_DECOR
2734
			|| vc->vc_num != fg_console
2735
#endif
2736
		)
2661
		return;
2737
		return;
2662
2738
2663
	if (!con_is_visible(vc))
2739
	if (!con_is_visible(vc))
Lines 2683-2689 static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table) Link Here
2683
	} else
2759
	} else
2684
		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2760
		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2685
2761
2686
	fb_set_cmap(&palette_cmap, info);
2762
	if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2763
	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2764
2765
		u16 *red, *green, *blue;
2766
		int minlen = min(min(info->var.red.length, info->var.green.length),
2767
				     info->var.blue.length);
2768
2769
		struct fb_cmap cmap = {
2770
			.start = 0,
2771
			.len = (1 << minlen),
2772
			.red = NULL,
2773
			.green = NULL,
2774
			.blue = NULL,
2775
			.transp = NULL
2776
		};
2777
2778
		red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
2779
2780
		if (!red)
2781
			goto out;
2782
2783
		green = red + 256;
2784
		blue = green + 256;
2785
		cmap.red = red;
2786
		cmap.green = green;
2787
		cmap.blue = blue;
2788
2789
		for (i = 0; i < cmap.len; i++)
2790
			red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
2791
2792
		fb_set_cmap(&cmap, info);
2793
		fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
2794
		kfree(red);
2795
2796
		return;
2797
2798
	} else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2799
		   info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
2800
		fb_set_cmap(&info->bgdecor.cmap, info);
2801
2802
out:	fb_set_cmap(&palette_cmap, info);
2687
}
2803
}
2688
2804
2689
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
2805
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
Lines 2908-2914 static void fbcon_modechanged(struct fb_info *info) Link Here
2908
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3024
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2909
		cols /= vc->vc_font.width;
3025
		cols /= vc->vc_font.width;
2910
		rows /= vc->vc_font.height;
3026
		rows /= vc->vc_font.height;
2911
		vc_resize(vc, cols, rows);
3027
3028
		if (!fbcon_decor_active_nores(info, vc)) {
3029
			vc_resize(vc, cols, rows);
3030
		} else {
3031
			fbcon_decor_disable(vc, 0);
3032
			fbcon_decor_call_helper("modechange", vc->vc_num);
3033
		}
3034
2912
		updatescrollmode(p, info, vc);
3035
		updatescrollmode(p, info, vc);
2913
		scrollback_max = 0;
3036
		scrollback_max = 0;
2914
		scrollback_current = 0;
3037
		scrollback_current = 0;
Lines 2953-2959 static void fbcon_set_all_vcs(struct fb_info *info) Link Here
2953
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3076
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2954
		cols /= vc->vc_font.width;
3077
		cols /= vc->vc_font.width;
2955
		rows /= vc->vc_font.height;
3078
		rows /= vc->vc_font.height;
2956
		vc_resize(vc, cols, rows);
3079
		if (!fbcon_decor_active_nores(info, vc))
3080
			vc_resize(vc, cols, rows);
2957
	}
3081
	}
2958
3082
2959
	if (fg != -1)
3083
	if (fg != -1)
Lines 3594-3599 static void fbcon_exit(void) Link Here
3594
		}
3718
		}
3595
	}
3719
	}
3596
3720
3721
	fbcon_decor_exit();
3597
	fbcon_has_exited = 1;
3722
	fbcon_has_exited = 1;
3598
}
3723
}
3599
3724
(-) (+549 lines)
Added Link Here
1
/*
2
 *  linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations
3
 *
4
 *  Copyright (C) 2004-2009 Michal Januszewski <michalj+fbcondecor@gmail.com>
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
#include <linux/binfmts.h>
39
#include <linux/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
48
static int initialized;
49
50
char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
51
EXPORT_SYMBOL(fbcon_decor_path);
52
53
int fbcon_decor_call_helper(char *cmd, unsigned short vc)
54
{
55
	char *envp[] = {
56
		"HOME=/",
57
		"PATH=/sbin:/bin",
58
		NULL
59
	};
60
61
	char tfb[5];
62
	char tcons[5];
63
	unsigned char fb = (int) con2fb_map[vc];
64
65
	char *argv[] = {
66
		fbcon_decor_path,
67
		"2",
68
		cmd,
69
		tcons,
70
		tfb,
71
		vc_cons[vc].d->vc_decor.theme,
72
		NULL
73
	};
74
75
	snprintf(tfb, 5, "%d", fb);
76
	snprintf(tcons, 5, "%d", vc);
77
78
	return call_usermodehelper(fbcon_decor_path, argv, envp, UMH_WAIT_EXEC);
79
}
80
81
/* Disables fbcondecor on a virtual console; called with console sem held. */
82
int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw)
83
{
84
	struct fb_info *info;
85
86
	if (!vc->vc_decor.state)
87
		return -EINVAL;
88
89
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
90
91
	if (info == NULL)
92
		return -EINVAL;
93
94
	vc->vc_decor.state = 0;
95
	vc_resize(vc, info->var.xres / vc->vc_font.width,
96
		  info->var.yres / vc->vc_font.height);
97
98
	if (fg_console == vc->vc_num && redraw) {
99
		redraw_screen(vc, 0);
100
		update_region(vc, vc->vc_origin +
101
			      vc->vc_size_row * vc->vc_top,
102
			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
103
	}
104
105
	printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n",
106
			 vc->vc_num);
107
108
	return 0;
109
}
110
111
/* Enables fbcondecor on a virtual console; called with console sem held. */
112
static int fbcon_decor_enable(struct vc_data *vc)
113
{
114
	struct fb_info *info;
115
116
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
117
118
	if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 ||
119
	    info == NULL || vc->vc_decor.state || (!info->bgdecor.data &&
120
	    vc->vc_num == fg_console))
121
		return -EINVAL;
122
123
	vc->vc_decor.state = 1;
124
	vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width,
125
		  vc->vc_decor.theight / vc->vc_font.height);
126
127
	if (fg_console == vc->vc_num) {
128
		redraw_screen(vc, 0);
129
		update_region(vc, vc->vc_origin +
130
			      vc->vc_size_row * vc->vc_top,
131
			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
132
		fbcon_decor_clear_margins(vc, info, 0);
133
	}
134
135
	printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n",
136
			 vc->vc_num);
137
138
	return 0;
139
}
140
141
static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin)
142
{
143
	int ret;
144
145
	console_lock();
146
	if (!state)
147
		ret = fbcon_decor_disable(vc, 1);
148
	else
149
		ret = fbcon_decor_enable(vc);
150
	console_unlock();
151
152
	return ret;
153
}
154
155
static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state)
156
{
157
	*state = vc->vc_decor.state;
158
}
159
160
static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin)
161
{
162
	struct fb_info *info;
163
	int len;
164
	char *tmp;
165
166
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
167
168
	if (info == NULL || !cfg->twidth || !cfg->theight ||
169
	    cfg->tx + cfg->twidth  > info->var.xres ||
170
	    cfg->ty + cfg->theight > info->var.yres)
171
		return -EINVAL;
172
173
	len = strnlen_user(cfg->theme, MAX_ARG_STRLEN);
174
	if (!len || len > FBCON_DECOR_THEME_LEN)
175
		return -EINVAL;
176
	tmp = kmalloc(len, GFP_KERNEL);
177
	if (!tmp)
178
		return -ENOMEM;
179
	if (copy_from_user(tmp, (void __user *)cfg->theme, len))
180
		return -EFAULT;
181
	cfg->theme = tmp;
182
	cfg->state = 0;
183
184
	console_lock();
185
	if (vc->vc_decor.state)
186
		fbcon_decor_disable(vc, 1);
187
	kfree(vc->vc_decor.theme);
188
	vc->vc_decor = *cfg;
189
	console_unlock();
190
191
	printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n",
192
			 vc->vc_num, vc->vc_decor.theme);
193
	return 0;
194
}
195
196
static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc,
197
					struct vc_decor *decor)
198
{
199
	char __user *tmp;
200
201
	tmp = decor->theme;
202
	*decor = vc->vc_decor;
203
	decor->theme = tmp;
204
205
	if (vc->vc_decor.theme) {
206
		if (copy_to_user(tmp, vc->vc_decor.theme,
207
					strlen(vc->vc_decor.theme) + 1))
208
			return -EFAULT;
209
	} else
210
		if (put_user(0, tmp))
211
			return -EFAULT;
212
213
	return 0;
214
}
215
216
static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img,
217
						unsigned char origin)
218
{
219
	struct fb_info *info;
220
	int len;
221
	u8 *tmp;
222
223
	if (vc->vc_num != fg_console)
224
		return -EINVAL;
225
226
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
227
228
	if (info == NULL)
229
		return -EINVAL;
230
231
	if (img->width != info->var.xres || img->height != info->var.yres) {
232
		printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n");
233
		printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height,
234
				info->var.xres, info->var.yres);
235
		return -EINVAL;
236
	}
237
238
	if (img->depth != info->var.bits_per_pixel) {
239
		printk(KERN_ERR "fbcondecor: picture depth mismatch\n");
240
		return -EINVAL;
241
	}
242
243
	if (img->depth == 8) {
244
		if (!img->cmap.len || !img->cmap.red || !img->cmap.green ||
245
		    !img->cmap.blue)
246
			return -EINVAL;
247
248
		tmp = vmalloc(img->cmap.len * 3 * 2);
249
		if (!tmp)
250
			return -ENOMEM;
251
252
		if (copy_from_user(tmp,
253
				(void __user *)img->cmap.red,
254
						(img->cmap.len << 1)) ||
255
			copy_from_user(tmp + (img->cmap.len << 1),
256
				(void __user *)img->cmap.green,
257
						(img->cmap.len << 1)) ||
258
			copy_from_user(tmp + (img->cmap.len << 2),
259
				(void __user *)img->cmap.blue,
260
						(img->cmap.len << 1))) {
261
			vfree(tmp);
262
			return -EFAULT;
263
		}
264
265
		img->cmap.transp = NULL;
266
		img->cmap.red = (u16 *)tmp;
267
		img->cmap.green = img->cmap.red + img->cmap.len;
268
		img->cmap.blue = img->cmap.green + img->cmap.len;
269
	} else {
270
		img->cmap.red = NULL;
271
	}
272
273
	len = ((img->depth + 7) >> 3) * img->width * img->height;
274
275
	/*
276
	 * Allocate an additional byte so that we never go outside of the
277
	 * buffer boundaries in the rendering functions in a 24 bpp mode.
278
	 */
279
	tmp = vmalloc(len + 1);
280
281
	if (!tmp)
282
		goto out;
283
284
	if (copy_from_user(tmp, (void __user *)img->data, len))
285
		goto out;
286
287
	img->data = tmp;
288
289
	console_lock();
290
291
	if (info->bgdecor.data)
292
		vfree((u8 *)info->bgdecor.data);
293
	if (info->bgdecor.cmap.red)
294
		vfree(info->bgdecor.cmap.red);
295
296
	info->bgdecor = *img;
297
298
	if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) {
299
		redraw_screen(vc, 0);
300
		update_region(vc, vc->vc_origin +
301
			      vc->vc_size_row * vc->vc_top,
302
			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
303
		fbcon_decor_clear_margins(vc, info, 0);
304
	}
305
306
	console_unlock();
307
308
	return 0;
309
310
out:
311
	if (img->cmap.red)
312
		vfree(img->cmap.red);
313
314
	if (tmp)
315
		vfree(tmp);
316
	return -ENOMEM;
317
}
318
319
static long fbcon_decor_ioctl(struct file *filp, u_int cmd, u_long arg)
320
{
321
	struct fbcon_decor_iowrapper __user *wrapper = (void __user *) arg;
322
	struct vc_data *vc = NULL;
323
	unsigned short vc_num = 0;
324
	unsigned char origin = 0;
325
	void __user *data = NULL;
326
327
	if (!access_ok(VERIFY_READ, wrapper,
328
			sizeof(struct fbcon_decor_iowrapper)))
329
		return -EFAULT;
330
331
	__get_user(vc_num, &wrapper->vc);
332
	__get_user(origin, &wrapper->origin);
333
	__get_user(data, &wrapper->data);
334
335
	if (!vc_cons_allocated(vc_num))
336
		return -EINVAL;
337
338
	vc = vc_cons[vc_num].d;
339
340
	switch (cmd) {
341
	case FBIOCONDECOR_SETPIC:
342
	{
343
		struct fb_image img;
344
345
		if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image)))
346
			return -EFAULT;
347
348
		return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
349
	}
350
	case FBIOCONDECOR_SETCFG:
351
	{
352
		struct vc_decor cfg;
353
354
		if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
355
			return -EFAULT;
356
357
		return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
358
	}
359
	case FBIOCONDECOR_GETCFG:
360
	{
361
		int rval;
362
		struct vc_decor cfg;
363
364
		if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
365
			return -EFAULT;
366
367
		rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
368
369
		if (copy_to_user(data, &cfg, sizeof(struct vc_decor)))
370
			return -EFAULT;
371
		return rval;
372
	}
373
	case FBIOCONDECOR_SETSTATE:
374
	{
375
		unsigned int state = 0;
376
377
		if (get_user(state, (unsigned int __user *)data))
378
			return -EFAULT;
379
		return fbcon_decor_ioctl_dosetstate(vc, state, origin);
380
	}
381
	case FBIOCONDECOR_GETSTATE:
382
	{
383
		unsigned int state = 0;
384
385
		fbcon_decor_ioctl_dogetstate(vc, &state);
386
		return put_user(state, (unsigned int __user *)data);
387
	}
388
389
	default:
390
		return -ENOIOCTLCMD;
391
	}
392
}
393
394
#ifdef CONFIG_COMPAT
395
396
static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
397
{
398
	struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg;
399
	struct vc_data *vc = NULL;
400
	unsigned short vc_num = 0;
401
	unsigned char origin = 0;
402
	compat_uptr_t data_compat = 0;
403
	void __user *data = NULL;
404
405
	if (!access_ok(VERIFY_READ, wrapper,
406
			sizeof(struct fbcon_decor_iowrapper32)))
407
		return -EFAULT;
408
409
	__get_user(vc_num, &wrapper->vc);
410
	__get_user(origin, &wrapper->origin);
411
	__get_user(data_compat, &wrapper->data);
412
	data = compat_ptr(data_compat);
413
414
	if (!vc_cons_allocated(vc_num))
415
		return -EINVAL;
416
417
	vc = vc_cons[vc_num].d;
418
419
	switch (cmd) {
420
	case FBIOCONDECOR_SETPIC32:
421
	{
422
		struct fb_image32 img_compat;
423
		struct fb_image img;
424
425
		if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32)))
426
			return -EFAULT;
427
428
		fb_image_from_compat(img, img_compat);
429
430
		return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
431
	}
432
433
	case FBIOCONDECOR_SETCFG32:
434
	{
435
		struct vc_decor32 cfg_compat;
436
		struct vc_decor cfg;
437
438
		if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
439
			return -EFAULT;
440
441
		vc_decor_from_compat(cfg, cfg_compat);
442
443
		return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
444
	}
445
446
	case FBIOCONDECOR_GETCFG32:
447
	{
448
		int rval;
449
		struct vc_decor32 cfg_compat;
450
		struct vc_decor cfg;
451
452
		if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
453
			return -EFAULT;
454
		cfg.theme = compat_ptr(cfg_compat.theme);
455
456
		rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
457
458
		vc_decor_to_compat(cfg_compat, cfg);
459
460
		if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32)))
461
			return -EFAULT;
462
		return rval;
463
	}
464
465
	case FBIOCONDECOR_SETSTATE32:
466
	{
467
		compat_uint_t state_compat = 0;
468
		unsigned int state = 0;
469
470
		if (get_user(state_compat, (compat_uint_t __user *)data))
471
			return -EFAULT;
472
473
		state = (unsigned int)state_compat;
474
475
		return fbcon_decor_ioctl_dosetstate(vc, state, origin);
476
	}
477
478
	case FBIOCONDECOR_GETSTATE32:
479
	{
480
		compat_uint_t state_compat = 0;
481
		unsigned int state = 0;
482
483
		fbcon_decor_ioctl_dogetstate(vc, &state);
484
		state_compat = (compat_uint_t)state;
485
486
		return put_user(state_compat, (compat_uint_t __user *)data);
487
	}
488
489
	default:
490
		return -ENOIOCTLCMD;
491
	}
492
}
493
#else
494
  #define fbcon_decor_compat_ioctl NULL
495
#endif
496
497
static struct file_operations fbcon_decor_ops = {
498
	.owner = THIS_MODULE,
499
	.unlocked_ioctl = fbcon_decor_ioctl,
500
	.compat_ioctl = fbcon_decor_compat_ioctl
501
};
502
503
static struct miscdevice fbcon_decor_dev = {
504
	.minor = MISC_DYNAMIC_MINOR,
505
	.name = "fbcondecor",
506
	.fops = &fbcon_decor_ops
507
};
508
509
void fbcon_decor_reset(void)
510
{
511
	int i;
512
513
	for (i = 0; i < num_registered_fb; i++) {
514
		registered_fb[i]->bgdecor.data = NULL;
515
		registered_fb[i]->bgdecor.cmap.red = NULL;
516
	}
517
518
	for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
519
		vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth =
520
						vc_cons[i].d->vc_decor.theight = 0;
521
		vc_cons[i].d->vc_decor.theme = NULL;
522
	}
523
}
524
525
int fbcon_decor_init(void)
526
{
527
	int i;
528
529
	fbcon_decor_reset();
530
531
	if (initialized)
532
		return 0;
533
534
	i = misc_register(&fbcon_decor_dev);
535
	if (i) {
536
		printk(KERN_ERR "fbcondecor: failed to register device\n");
537
		return i;
538
	}
539
540
	fbcon_decor_call_helper("init", 0);
541
	initialized = 1;
542
	return 0;
543
}
544
545
int fbcon_decor_exit(void)
546
{
547
	fbcon_decor_reset();
548
	return 0;
549
}
(-)a/drivers/video/console/fbcondecor.h (+77 lines)
Line 0 Link Here
1
/*
2
 *  linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers
3
 *
4
 *  Copyright (C) 2004 Michal Januszewski <michalj+fbcondecor@gmail.com>
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
#else /* CONFIG_FB_CON_DECOR */
57
58
static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
59
static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
60
static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
61
static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
62
static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
63
static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
64
static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
65
static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
66
static inline int fbcon_decor_call_helper(char *cmd, unsigned short cons) { return 0; }
67
static inline int fbcon_decor_init(void) { return 0; }
68
static inline int fbcon_decor_exit(void) { return 0; }
69
static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
70
71
#define fbcon_decor_active_vc(y) (0)
72
#define fbcon_decor_active_nores(x, y) (0)
73
#define fbcon_decor_active(x, y) (0)
74
75
#endif /* CONFIG_FB_CON_DECOR */
76
77
#endif /* __FBCON_DECOR_H */
(-)a/drivers/video/fbdev/Kconfig (-1 lines)
Lines 1216-1222 config FB_MATROX Link Here
1216
	select FB_CFB_FILLRECT
1216
	select FB_CFB_FILLRECT
1217
	select FB_CFB_COPYAREA
1217
	select FB_CFB_COPYAREA
1218
	select FB_CFB_IMAGEBLIT
1218
	select FB_CFB_IMAGEBLIT
1219
	select FB_TILEBLITTING
1220
	select FB_MACMODES if PPC_PMAC
1219
	select FB_MACMODES if PPC_PMAC
1221
	---help---
1220
	---help---
1222
	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
1221
	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
(-)a/drivers/video/fbdev/core/fbcmap.c (-2 / +7 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 254-262 int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) Link Here
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/fbdev/core/fbmem.c (-9 lines)
Lines 1251-1265 struct fb_fix_screeninfo32 { Link Here
1251
	u16			reserved[3];
1251
	u16			reserved[3];
1252
};
1252
};
1253
1253
1254
struct fb_cmap32 {
1255
	u32			start;
1256
	u32			len;
1257
	compat_caddr_t	red;
1258
	compat_caddr_t	green;
1259
	compat_caddr_t	blue;
1260
	compat_caddr_t	transp;
1261
};
1262
1263
static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1254
static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1264
			  unsigned long arg)
1255
			  unsigned long arg)
1265
{
1256
{
(-)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 20-25 struct vt_struct; Link Here
20
struct uni_pagedir;
20
struct uni_pagedir;
21
21
22
#define NPAR 16
22
#define NPAR 16
23
#include <linux/console_decor.h>
23
24
24
/*
25
/*
25
 * Example: vc_data of a console that was scrolled 3 lines down.
26
 * Example: vc_data of a console that was scrolled 3 lines down.
Lines 140-145 struct vc_data { Link Here
140
	struct uni_pagedir *vc_uni_pagedir;
141
	struct uni_pagedir *vc_uni_pagedir;
141
	struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
142
	struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
142
	bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
143
	bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
144
145
	struct vc_decor vc_decor;
143
	/* additional information is in vt_kern.h */
146
	/* additional information is in vt_kern.h */
144
};
147
};
145
148
(-)a/include/linux/fb.h (+31 lines)
Lines 238-243 struct fb_deferred_io { Link Here
238
};
238
};
239
#endif
239
#endif
240
240
241
#ifdef __KERNEL__
242
#ifdef CONFIG_COMPAT
243
struct fb_image32 {
244
	__u32 dx;			/* Where to place image */
245
	__u32 dy;
246
	__u32 width;			/* Size of image */
247
	__u32 height;
248
	__u32 fg_color;			/* Only used when a mono bitmap */
249
	__u32 bg_color;
250
	__u8  depth;			/* Depth of the image */
251
	const compat_uptr_t data;	/* Pointer to image data */
252
	struct fb_cmap32 cmap;		/* color map info */
253
};
254
255
#define fb_image_from_compat(to, from) \
256
	(to).dx       = (from).dx; \
257
	(to).dy       = (from).dy; \
258
	(to).width    = (from).width; \
259
	(to).height   = (from).height; \
260
	(to).fg_color = (from).fg_color; \
261
	(to).bg_color = (from).bg_color; \
262
	(to).depth    = (from).depth; \
263
	(to).data     = compat_ptr((from).data); \
264
	fb_cmap_from_compat((to).cmap, (from).cmap)
265
266
#endif /* CONFIG_COMPAT */
267
#endif /* __KERNEL__ */
268
241
/*
269
/*
242
 * Frame buffer operations
270
 * Frame buffer operations
243
 *
271
 *
Lines 508-513 struct fb_info { Link Here
508
#define FBINFO_STATE_SUSPENDED	1
536
#define FBINFO_STATE_SUSPENDED	1
509
	u32 state;			/* Hardware state i.e suspend */
537
	u32 state;			/* Hardware state i.e suspend */
510
	void *fbcon_par;                /* fbcon use-only private area */
538
	void *fbcon_par;                /* fbcon use-only private area */
539
540
	struct fb_image bgdecor;
541
511
	/* From here on everything is device dependent */
542
	/* From here on everything is device dependent */
512
	void *par;
543
	void *par;
513
	/* we need the PCI or similar aperture base/size not
544
	/* we need the PCI or similar aperture base/size not
(-)a/include/uapi/linux/fb.h (+59 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
	unsigned short vc;		/* Virtual console */
13
	unsigned char origin;		/* Point of origin of the request */
14
	void *data;
15
};
16
17
#ifdef __KERNEL__
18
#ifdef CONFIG_COMPAT
19
#include <linux/compat.h>
20
struct fbcon_decor_iowrapper32 {
21
	unsigned short vc;		/* Virtual console */
22
	unsigned char origin;		/* Point of origin of the request */
23
	compat_uptr_t data;
24
};
25
#endif /* CONFIG_COMPAT */
26
#endif /* __KERNEL__ */
27
11
/* ioctls
28
/* ioctls
12
   0x46 is 'F'								*/
29
   0x46 is 'F'								*/
13
#define FBIOGET_VSCREENINFO	0x4600
30
#define FBIOGET_VSCREENINFO	0x4600
Lines 35-40 Link Here
35
#define FBIOGET_DISPINFO        0x4618
52
#define FBIOGET_DISPINFO        0x4618
36
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
53
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
37
54
55
#define FBIOCONDECOR_SETCFG	_IOWR('F', 0x19, struct fbcon_decor_iowrapper)
56
#define FBIOCONDECOR_GETCFG	_IOR('F', 0x1A, struct fbcon_decor_iowrapper)
57
#define FBIOCONDECOR_SETSTATE	_IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
58
#define FBIOCONDECOR_GETSTATE	_IOR('F', 0x1C, struct fbcon_decor_iowrapper)
59
#define FBIOCONDECOR_SETPIC	_IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
60
#ifdef __KERNEL__
61
#ifdef CONFIG_COMPAT
62
#define FBIOCONDECOR_SETCFG32	_IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
63
#define FBIOCONDECOR_GETCFG32	_IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
64
#define FBIOCONDECOR_SETSTATE32	_IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
65
#define FBIOCONDECOR_GETSTATE32	_IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
66
#define FBIOCONDECOR_SETPIC32	_IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
67
#endif /* CONFIG_COMPAT */
68
#endif /* __KERNEL__ */
69
70
#define FBCON_DECOR_THEME_LEN		128	/* Maximum length of a theme name */
71
#define FBCON_DECOR_IO_ORIG_KERNEL	0	/* Kernel ioctl origin */
72
#define FBCON_DECOR_IO_ORIG_USER	1	/* User ioctl origin */
73
38
#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
74
#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
39
#define FB_TYPE_PLANES			1	/* Non interleaved planes */
75
#define FB_TYPE_PLANES			1	/* Non interleaved planes */
40
#define FB_TYPE_INTERLEAVED_PLANES	2	/* Interleaved planes	*/
76
#define FB_TYPE_INTERLEAVED_PLANES	2	/* Interleaved planes	*/
Lines 277-282 struct fb_var_screeninfo { Link Here
277
	__u32 reserved[4];		/* Reserved for future compatibility */
313
	__u32 reserved[4];		/* Reserved for future compatibility */
278
};
314
};
279
315
316
#ifdef __KERNEL__
317
#ifdef CONFIG_COMPAT
318
struct fb_cmap32 {
319
	__u32 start;
320
	__u32 len;			/* Number of entries */
321
	compat_uptr_t red;		/* Red values	*/
322
	compat_uptr_t green;
323
	compat_uptr_t blue;
324
	compat_uptr_t transp;		/* transparency, can be NULL */
325
};
326
327
#define fb_cmap_from_compat(to, from) \
328
	(to).start  = (from).start; \
329
	(to).len    = (from).len; \
330
	(to).red    = compat_ptr((from).red); \
331
	(to).green  = compat_ptr((from).green); \
332
	(to).blue   = compat_ptr((from).blue); \
333
	(to).transp = compat_ptr((from).transp)
334
335
#endif /* CONFIG_COMPAT */
336
#endif /* __KERNEL__ */
337
338
280
struct fb_cmap {
339
struct fb_cmap {
281
	__u32 start;			/* First entry	*/
340
	__u32 start;			/* First entry	*/
282
	__u32 len;			/* Number of entries */
341
	__u32 len;			/* Number of entries */
(-)a/kernel/sysctl.c (+13 lines)
Lines 149-154 static const int cap_last_cap = CAP_LAST_CAP; Link Here
149
static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
149
static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
150
#endif
150
#endif
151
151
152
#ifdef CONFIG_FB_CON_DECOR
153
extern char fbcon_decor_path[];
154
#endif
155
152
#ifdef CONFIG_INOTIFY_USER
156
#ifdef CONFIG_INOTIFY_USER
153
#include <linux/inotify.h>
157
#include <linux/inotify.h>
154
#endif
158
#endif
Lines 266-271 static struct ctl_table sysctl_base_table[] = { Link Here
266
		.mode		= 0555,
270
		.mode		= 0555,
267
		.child		= dev_table,
271
		.child		= dev_table,
268
	},
272
	},
273
#ifdef CONFIG_FB_CON_DECOR
274
	{
275
		.procname	= "fbcondecor",
276
		.data		= &fbcon_decor_path,
277
		.maxlen		= KMOD_PATH_LEN,
278
		.mode		= 0644,
279
		.proc_handler	= &proc_dostring,
280
	},
281
#endif
269
	{ }
282
	{ }
270
};
283
};
271
284

Return to bug 629860