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

(-)linux-4.20.3-gentoo/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
(-)linux-4.20.3-gentoo/drivers/Makefile (-5 / +4 lines)
Lines 20-25 Link Here
20
20
21
obj-$(CONFIG_PARISC)		+= parisc/
21
obj-$(CONFIG_PARISC)		+= parisc/
22
obj-$(CONFIG_RAPIDIO)		+= rapidio/
22
obj-$(CONFIG_RAPIDIO)		+= rapidio/
23
# tty/ comes before char/ so that the VT console is the boot-time
24
# default.
25
obj-y				+= tty/
26
obj-y				+= char/
23
obj-y				+= video/
27
obj-y				+= video/
24
obj-y				+= idle/
28
obj-y				+= idle/
25
29
Lines 50-60 Link Here
50
# reset controllers early, since gpu drivers might rely on them to initialize
54
# reset controllers early, since gpu drivers might rely on them to initialize
51
obj-$(CONFIG_RESET_CONTROLLER)	+= reset/
55
obj-$(CONFIG_RESET_CONTROLLER)	+= reset/
52
56
53
# tty/ comes before char/ so that the VT console is the boot-time
54
# default.
55
obj-y				+= tty/
56
obj-y				+= char/
57
58
# iommu/ comes before gpu as gpu are using iommu controllers
57
# iommu/ comes before gpu as gpu are using iommu controllers
59
obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
58
obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
60
59
(-)linux-4.20.3-gentoo/drivers/video/console/Kconfig (+13 lines)
Lines 161-166 Link Here
161
	  by the firmware in place, rather then replacing the contents with a
161
	  by the firmware in place, rather then replacing the contents with a
162
	  black screen as soon as fbcon loads.
162
	  black screen as soon as fbcon loads.
163
163
164
config FB_CON_DECOR
165
	bool "Support for the Framebuffer Console Decorations"
166
	depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
167
	default n
168
	---help---
169
	  This option enables support for framebuffer console decorations which
170
	  makes it possible to display images in the background of the system
171
	  consoles.  Note that userspace utilities are necessary in order to take
172
	  advantage of these features. Refer to Documentation/fb/fbcondecor.txt
173
	  for more information.
174
175
	  If unsure, say N.
176
164
config STI_CONSOLE
177
config STI_CONSOLE
165
        bool "STI text console"
178
        bool "STI text console"
166
	depends on PARISC && HAS_IOMEM
179
	depends on PARISC && HAS_IOMEM
(-)linux-4.20.3-gentoo/drivers/video/console/Makefile (+1 lines)
Lines 9-12 Link Here
9
obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
9
obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
10
obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
10
obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
11
11
12
obj-$(CONFIG_FB_CON_DECOR)     	  += fbcondecor.o cfbcondecor.o
12
obj-$(CONFIG_FB_STI)              += sticore.o
13
obj-$(CONFIG_FB_STI)              += sticore.o
(-)linux-4.20.3-gentoo/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 "../fbdev/core/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
(-)linux-4.20.3-gentoo/drivers/video/console/fbcondecor.c (+549 lines)
Line 0 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 "../fbdev/core/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
}
(-)linux-4.20.3-gentoo/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 */
(-)linux-4.20.3-gentoo/drivers/video/fbdev/Kconfig (-1 lines)
Lines 1092-1098 Link Here
1092
	select FB_CFB_FILLRECT
1092
	select FB_CFB_FILLRECT
1093
	select FB_CFB_COPYAREA
1093
	select FB_CFB_COPYAREA
1094
	select FB_CFB_IMAGEBLIT
1094
	select FB_CFB_IMAGEBLIT
1095
	select FB_TILEBLITTING
1096
	select FB_MACMODES if PPC_PMAC
1095
	select FB_MACMODES if PPC_PMAC
1097
	---help---
1096
	---help---
1098
	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
1097
	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
(-)linux-4.20.3-gentoo/drivers/video/fbdev/core/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 "../../console/fbcondecor.h"
21
22
22
/*
23
/*
23
 * Accelerated handlers.
24
 * Accelerated handlers.
Lines 55-60 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 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
}
(-)linux-4.20.3-gentoo/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 256-264 Link Here
256
				break;
258
				break;
257
		}
259
		}
258
	}
260
	}
259
	if (rc == 0)
261
	if (rc == 0) {
260
		fb_copy_cmap(cmap, &info->cmap);
262
		fb_copy_cmap(cmap, &info->cmap);
261
263
		if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
264
		    info->fix.visual == FB_VISUAL_DIRECTCOLOR)
265
			fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
266
	}
262
	return rc;
267
	return rc;
263
}
268
}
264
269
(-)linux-4.20.3-gentoo/drivers/video/fbdev/core/fbcon.c (-23 / +148 lines)
Lines 80-85 Link Here
80
#include <asm/irq.h>
80
#include <asm/irq.h>
81
81
82
#include "fbcon.h"
82
#include "fbcon.h"
83
#include "../../console/fbcondecor.h"
83
84
84
#ifdef FBCONDEBUG
85
#ifdef FBCONDEBUG
85
#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
86
#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
Lines 95-101 Link Here
95
96
96
static struct display fb_display[MAX_NR_CONSOLES];
97
static struct display fb_display[MAX_NR_CONSOLES];
97
98
98
static signed char con2fb_map[MAX_NR_CONSOLES];
99
signed char con2fb_map[MAX_NR_CONSOLES];
99
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
100
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
100
101
101
static int logo_lines;
102
static int logo_lines;
Lines 287-293 Link Here
287
		vc->vc_mode != KD_TEXT || ops->graphics);
288
		vc->vc_mode != KD_TEXT || ops->graphics);
288
}
289
}
289
290
290
static int get_color(struct vc_data *vc, struct fb_info *info,
291
int get_color(struct vc_data *vc, struct fb_info *info,
291
	      u16 c, int is_fg)
292
	      u16 c, int is_fg)
292
{
293
{
293
	int depth = fb_get_color_depth(&info->var, &info->fix);
294
	int depth = fb_get_color_depth(&info->var, &info->fix);
Lines 561-566 Link Here
561
		info_idx = -1;
562
		info_idx = -1;
562
	} else {
563
	} else {
563
		fbcon_has_console_bind = 1;
564
		fbcon_has_console_bind = 1;
565
#ifdef CONFIG_FB_CON_DECOR
566
		fbcon_decor_init();
567
#endif
564
	}
568
	}
565
569
566
	return err;
570
	return err;
Lines 1031-1036 Link Here
1031
	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1035
	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1032
	cols /= vc->vc_font.width;
1036
	cols /= vc->vc_font.width;
1033
	rows /= vc->vc_font.height;
1037
	rows /= vc->vc_font.height;
1038
1039
	if (fbcon_decor_active(info, vc)) {
1040
		cols = vc->vc_decor.twidth / vc->vc_font.width;
1041
		rows = vc->vc_decor.theight / vc->vc_font.height;
1042
	}
1043
1034
	vc_resize(vc, cols, rows);
1044
	vc_resize(vc, cols, rows);
1035
1045
1036
	DPRINTK("mode:   %s\n", info->fix.id);
1046
	DPRINTK("mode:   %s\n", info->fix.id);
Lines 1060-1066 Link Here
1060
	cap = info->flags;
1070
	cap = info->flags;
1061
1071
1062
	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1072
	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
1063
	    (info->fix.type == FB_TYPE_TEXT))
1073
	    (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
1064
		logo = 0;
1074
		logo = 0;
1065
1075
1066
	if (var_to_display(p, &info->var, info))
1076
	if (var_to_display(p, &info->var, info))
Lines 1295-1300 Link Here
1295
		fbcon_clear_margins(vc, 0);
1305
		fbcon_clear_margins(vc, 0);
1296
	}
1306
	}
1297
1307
1308
	if (fbcon_decor_active(info, vc)) {
1309
		fbcon_decor_clear(vc, info, sy, sx, height, width);
1310
		return;
1311
	}
1312
1298
	/* Split blits that cross physical y_wrap boundary */
1313
	/* Split blits that cross physical y_wrap boundary */
1299
1314
1300
	y_break = p->vrows - p->yscroll;
1315
	y_break = p->vrows - p->yscroll;
Lines 1314-1323 Link Here
1314
	struct display *p = &fb_display[vc->vc_num];
1329
	struct display *p = &fb_display[vc->vc_num];
1315
	struct fbcon_ops *ops = info->fbcon_par;
1330
	struct fbcon_ops *ops = info->fbcon_par;
1316
1331
1317
	if (!fbcon_is_inactive(vc, info))
1332
	if (!fbcon_is_inactive(vc, info)) {
1318
		ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1333
1319
			   get_color(vc, info, scr_readw(s), 1),
1334
		if (fbcon_decor_active(info, vc))
1320
			   get_color(vc, info, scr_readw(s), 0));
1335
			fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
1336
		else
1337
			ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
1338
				   get_color(vc, info, scr_readw(s), 1),
1339
				   get_color(vc, info, scr_readw(s), 0));
1340
	}
1321
}
1341
}
1322
1342
1323
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
1343
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
Lines 1333-1340 Link Here
1333
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1353
	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1334
	struct fbcon_ops *ops = info->fbcon_par;
1354
	struct fbcon_ops *ops = info->fbcon_par;
1335
1355
1336
	if (!fbcon_is_inactive(vc, info))
1356
	if (!fbcon_is_inactive(vc, info)) {
1337
		ops->clear_margins(vc, info, margin_color, bottom_only);
1357
		if (fbcon_decor_active(info, vc))
1358
			fbcon_decor_clear_margins(vc, info, bottom_only);
1359
		else
1360
			ops->clear_margins(vc, info, margin_color, bottom_only);
1361
	}
1338
}
1362
}
1339
1363
1340
static void fbcon_cursor(struct vc_data *vc, int mode)
1364
static void fbcon_cursor(struct vc_data *vc, int mode)
Lines 1855-1861 Link Here
1855
			count = vc->vc_rows;
1879
			count = vc->vc_rows;
1856
		if (softback_top)
1880
		if (softback_top)
1857
			fbcon_softback_note(vc, t, count);
1881
			fbcon_softback_note(vc, t, count);
1858
		if (logo_shown >= 0)
1882
		if (logo_shown >= 0 || fbcon_decor_active(info, vc))
1859
			goto redraw_up;
1883
			goto redraw_up;
1860
		switch (p->scrollmode) {
1884
		switch (p->scrollmode) {
1861
		case SCROLL_MOVE:
1885
		case SCROLL_MOVE:
Lines 1948-1953 Link Here
1948
			count = vc->vc_rows;
1972
			count = vc->vc_rows;
1949
		if (logo_shown >= 0)
1973
		if (logo_shown >= 0)
1950
			goto redraw_down;
1974
			goto redraw_down;
1975
		if (fbcon_decor_active(info, vc))
1976
			goto redraw_down;
1951
		switch (p->scrollmode) {
1977
		switch (p->scrollmode) {
1952
		case SCROLL_MOVE:
1978
		case SCROLL_MOVE:
1953
			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
1979
			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
Lines 2096-2101 Link Here
2096
		}
2122
		}
2097
		return;
2123
		return;
2098
	}
2124
	}
2125
2126
	if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
2127
		/* must use slower redraw bmove to keep background pic intact */
2128
		fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
2129
		return;
2130
	}
2131
2099
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2132
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2100
		   height, width);
2133
		   height, width);
2101
}
2134
}
Lines 2166-2173 Link Here
2166
	var.yres = virt_h * virt_fh;
2199
	var.yres = virt_h * virt_fh;
2167
	x_diff = info->var.xres - var.xres;
2200
	x_diff = info->var.xres - var.xres;
2168
	y_diff = info->var.yres - var.yres;
2201
	y_diff = info->var.yres - var.yres;
2169
	if (x_diff < 0 || x_diff > virt_fw ||
2202
	if ((x_diff < 0 || x_diff > virt_fw ||
2170
	    y_diff < 0 || y_diff > virt_fh) {
2203
		y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
2171
		const struct fb_videomode *mode;
2204
		const struct fb_videomode *mode;
2172
2205
2173
		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
2206
		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
Lines 2203-2208 Link Here
2203
2236
2204
	info = registered_fb[con2fb_map[vc->vc_num]];
2237
	info = registered_fb[con2fb_map[vc->vc_num]];
2205
	ops = info->fbcon_par;
2238
	ops = info->fbcon_par;
2239
	prev_console = ops->currcon;
2240
	if (prev_console != -1)
2241
		old_info = registered_fb[con2fb_map[prev_console]];
2242
2243
#ifdef CONFIG_FB_CON_DECOR
2244
	if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2245
		struct vc_data *vc_curr = vc_cons[prev_console].d;
2246
2247
		if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
2248
			// Clear the screen to avoid displaying funky colors
2249
			// during palette updates.
2250
			memset((u8 *)info->screen_base + info->fix.line_length * info->var.yoffset,
2251
			       0, info->var.yres * info->fix.line_length);
2252
		}
2253
	}
2254
#endif
2206
2255
2207
	if (softback_top) {
2256
	if (softback_top) {
2208
		if (softback_lines)
2257
		if (softback_lines)
Lines 2221-2229 Link Here
2221
		logo_shown = FBCON_LOGO_CANSHOW;
2270
		logo_shown = FBCON_LOGO_CANSHOW;
2222
	}
2271
	}
2223
2272
2224
	prev_console = ops->currcon;
2225
	if (prev_console != -1)
2226
		old_info = registered_fb[con2fb_map[prev_console]];
2227
	/*
2273
	/*
2228
	 * FIXME: If we have multiple fbdev's loaded, we need to
2274
	 * FIXME: If we have multiple fbdev's loaded, we need to
2229
	 * update all info->currcon.  Perhaps, we can place this
2275
	 * update all info->currcon.  Perhaps, we can place this
Lines 2267-2272 Link Here
2267
			fbcon_del_cursor_timer(old_info);
2313
			fbcon_del_cursor_timer(old_info);
2268
	}
2314
	}
2269
2315
2316
	if (fbcon_decor_active_vc(vc)) {
2317
		struct vc_data *vc_curr = vc_cons[prev_console].d;
2318
2319
		if (!vc_curr->vc_decor.theme ||
2320
			strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
2321
			(fbcon_decor_active_nores(info, vc_curr) &&
2322
			 !fbcon_decor_active(info, vc_curr))) {
2323
			fbcon_decor_disable(vc, 0);
2324
			fbcon_decor_call_helper("modechange", vc->vc_num);
2325
		}
2326
	}
2327
2270
	if (fbcon_is_inactive(vc, info) ||
2328
	if (fbcon_is_inactive(vc, info) ||
2271
	    ops->blank_state != FB_BLANK_UNBLANK)
2329
	    ops->blank_state != FB_BLANK_UNBLANK)
2272
		fbcon_del_cursor_timer(info);
2330
		fbcon_del_cursor_timer(info);
Lines 2375-2389 Link Here
2375
		}
2433
		}
2376
	}
2434
	}
2377
2435
2378
 	if (!fbcon_is_inactive(vc, info)) {
2436
	if (!fbcon_is_inactive(vc, info)) {
2379
		if (ops->blank_state != blank) {
2437
		if (ops->blank_state != blank) {
2380
			ops->blank_state = blank;
2438
			ops->blank_state = blank;
2381
			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2439
			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2382
			ops->cursor_flash = (!blank);
2440
			ops->cursor_flash = (!blank);
2383
2441
2384
			if (!(info->flags & FBINFO_MISC_USEREVENT))
2442
			if (!(info->flags & FBINFO_MISC_USEREVENT)) {
2385
				if (fb_blank(info, blank))
2443
				if (fb_blank(info, blank)) {
2386
					fbcon_generic_blank(vc, info, blank);
2444
					if (fbcon_decor_active(info, vc))
2445
						fbcon_decor_blank(vc, info, blank);
2446
					else
2447
						fbcon_generic_blank(vc, info, blank);
2448
				}
2449
			}
2387
		}
2450
		}
2388
2451
2389
		if (!blank)
2452
		if (!blank)
Lines 2566-2578 Link Here
2566
		set_vc_hi_font(vc, true);
2629
		set_vc_hi_font(vc, true);
2567
2630
2568
	if (resize) {
2631
	if (resize) {
2632
		/* reset wrap/pan */
2569
		int cols, rows;
2633
		int cols, rows;
2570
2634
2571
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2635
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2572
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2636
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2637
2638
		if (fbcon_decor_active(info, vc)) {
2639
			info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2640
			cols = vc->vc_decor.twidth;
2641
			rows = vc->vc_decor.theight;
2642
		}
2573
		cols /= w;
2643
		cols /= w;
2574
		rows /= h;
2644
		rows /= h;
2645
2575
		vc_resize(vc, cols, rows);
2646
		vc_resize(vc, cols, rows);
2647
2576
		if (con_is_visible(vc) && softback_buf)
2648
		if (con_is_visible(vc) && softback_buf)
2577
			fbcon_update_softback(vc);
2649
			fbcon_update_softback(vc);
2578
	} else if (con_is_visible(vc)
2650
	} else if (con_is_visible(vc)
Lines 2702-2708 Link Here
2702
	int i, j, k, depth;
2774
	int i, j, k, depth;
2703
	u8 val;
2775
	u8 val;
2704
2776
2705
	if (fbcon_is_inactive(vc, info))
2777
	if (fbcon_is_inactive(vc, info)
2778
#ifdef CONFIG_FB_CON_DECOR
2779
			|| vc->vc_num != fg_console
2780
#endif
2781
		)
2706
		return;
2782
		return;
2707
2783
2708
	if (!con_is_visible(vc))
2784
	if (!con_is_visible(vc))
Lines 2728-2734 Link Here
2728
	} else
2804
	} else
2729
		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2805
		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
2730
2806
2731
	fb_set_cmap(&palette_cmap, info);
2807
	if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2808
	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
2809
2810
		u16 *red, *green, *blue;
2811
		int minlen = min(min(info->var.red.length, info->var.green.length),
2812
				     info->var.blue.length);
2813
2814
		struct fb_cmap cmap = {
2815
			.start = 0,
2816
			.len = (1 << minlen),
2817
			.red = NULL,
2818
			.green = NULL,
2819
			.blue = NULL,
2820
			.transp = NULL
2821
		};
2822
2823
		red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
2824
2825
		if (!red)
2826
			goto out;
2827
2828
		green = red + 256;
2829
		blue = green + 256;
2830
		cmap.red = red;
2831
		cmap.green = green;
2832
		cmap.blue = blue;
2833
2834
		for (i = 0; i < cmap.len; i++)
2835
			red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
2836
2837
		fb_set_cmap(&cmap, info);
2838
		fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
2839
		kfree(red);
2840
2841
		return;
2842
2843
	} else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
2844
		   info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
2845
		fb_set_cmap(&info->bgdecor.cmap, info);
2846
2847
out:	fb_set_cmap(&palette_cmap, info);
2732
}
2848
}
2733
2849
2734
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
2850
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
Lines 2953-2959 Link Here
2953
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3069
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2954
		cols /= vc->vc_font.width;
3070
		cols /= vc->vc_font.width;
2955
		rows /= vc->vc_font.height;
3071
		rows /= vc->vc_font.height;
2956
		vc_resize(vc, cols, rows);
3072
3073
		if (!fbcon_decor_active_nores(info, vc)) {
3074
			vc_resize(vc, cols, rows);
3075
		} else {
3076
			fbcon_decor_disable(vc, 0);
3077
			fbcon_decor_call_helper("modechange", vc->vc_num);
3078
		}
3079
2957
		updatescrollmode(p, info, vc);
3080
		updatescrollmode(p, info, vc);
2958
		scrollback_max = 0;
3081
		scrollback_max = 0;
2959
		scrollback_current = 0;
3082
		scrollback_current = 0;
Lines 2998-3004 Link Here
2998
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
3121
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2999
		cols /= vc->vc_font.width;
3122
		cols /= vc->vc_font.width;
3000
		rows /= vc->vc_font.height;
3123
		rows /= vc->vc_font.height;
3001
		vc_resize(vc, cols, rows);
3124
		if (!fbcon_decor_active_nores(info, vc))
3125
			vc_resize(vc, cols, rows);
3002
	}
3126
	}
3003
3127
3004
	if (fg != -1)
3128
	if (fg != -1)
Lines 3706-3711 Link Here
3706
		}
3830
		}
3707
	}
3831
	}
3708
3832
3833
	fbcon_decor_exit();
3709
	fbcon_has_exited = 1;
3834
	fbcon_has_exited = 1;
3710
}
3835
}
3711
3836
(-)linux-4.20.3-gentoo/drivers/video/fbdev/core/fbmem.c (-9 lines)
Lines 1244-1258 Link Here
1244
	u16			reserved[3];
1244
	u16			reserved[3];
1245
};
1245
};
1246
1246
1247
struct fb_cmap32 {
1248
	u32			start;
1249
	u32			len;
1250
	compat_caddr_t	red;
1251
	compat_caddr_t	green;
1252
	compat_caddr_t	blue;
1253
	compat_caddr_t	transp;
1254
};
1255
1256
static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1247
static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
1257
			  unsigned long arg)
1248
			  unsigned long arg)
1258
{
1249
{
(-)linux-4.20.3-gentoo/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
(-)linux-4.20.3-gentoo/include/linux/console_struct.h (+3 lines)
Lines 21-26 Link Here
21
struct uni_screen;
21
struct uni_screen;
22
22
23
#define NPAR 16
23
#define NPAR 16
24
#include <linux/console_decor.h>
24
25
25
/*
26
/*
26
 * Example: vc_data of a console that was scrolled 3 lines down.
27
 * Example: vc_data of a console that was scrolled 3 lines down.
Lines 141-146 Link Here
141
	struct uni_pagedir *vc_uni_pagedir;
142
	struct uni_pagedir *vc_uni_pagedir;
142
	struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
143
	struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
143
	struct uni_screen *vc_uni_screen;	/* unicode screen content */
144
	struct uni_screen *vc_uni_screen;	/* unicode screen content */
145
146
	struct vc_decor vc_decor;
144
	/* additional information is in vt_kern.h */
147
	/* additional information is in vt_kern.h */
145
};
148
};
146
149
(-)linux-4.20.3-gentoo/include/linux/fb.h (+31 lines)
Lines 239-244 Link Here
239
};
239
};
240
#endif
240
#endif
241
241
242
#ifdef __KERNEL__
243
#ifdef CONFIG_COMPAT
244
struct fb_image32 {
245
	__u32 dx;			/* Where to place image */
246
	__u32 dy;
247
	__u32 width;			/* Size of image */
248
	__u32 height;
249
	__u32 fg_color;			/* Only used when a mono bitmap */
250
	__u32 bg_color;
251
	__u8  depth;			/* Depth of the image */
252
	const compat_uptr_t data;	/* Pointer to image data */
253
	struct fb_cmap32 cmap;		/* color map info */
254
};
255
256
#define fb_image_from_compat(to, from) \
257
	(to).dx       = (from).dx; \
258
	(to).dy       = (from).dy; \
259
	(to).width    = (from).width; \
260
	(to).height   = (from).height; \
261
	(to).fg_color = (from).fg_color; \
262
	(to).bg_color = (from).bg_color; \
263
	(to).depth    = (from).depth; \
264
	(to).data     = compat_ptr((from).data); \
265
	fb_cmap_from_compat((to).cmap, (from).cmap)
266
267
#endif /* CONFIG_COMPAT */
268
#endif /* __KERNEL__ */
269
242
/*
270
/*
243
 * Frame buffer operations
271
 * Frame buffer operations
244
 *
272
 *
Lines 517-522 Link Here
517
#define FBINFO_STATE_SUSPENDED	1
545
#define FBINFO_STATE_SUSPENDED	1
518
	u32 state;			/* Hardware state i.e suspend */
546
	u32 state;			/* Hardware state i.e suspend */
519
	void *fbcon_par;                /* fbcon use-only private area */
547
	void *fbcon_par;                /* fbcon use-only private area */
548
549
	struct fb_image bgdecor;
550
520
	/* From here on everything is device dependent */
551
	/* From here on everything is device dependent */
521
	void *par;
552
	void *par;
522
	/* we need the PCI or similar aperture base/size not
553
	/* we need the PCI or similar aperture base/size not
(-)linux-4.20.3-gentoo/include/uapi/linux/fb.h (+59 lines)
Lines 9-14 Link Here
9
9
10
#define FB_MAX			32	/* sufficient for now */
10
#define FB_MAX			32	/* sufficient for now */
11
11
12
struct fbcon_decor_iowrapper {
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
	unsigned short vc;		/* Virtual console */
23
	unsigned char origin;		/* Point of origin of the request */
24
	compat_uptr_t data;
25
};
26
#endif /* CONFIG_COMPAT */
27
#endif /* __KERNEL__ */
28
12
/* ioctls
29
/* ioctls
13
   0x46 is 'F'								*/
30
   0x46 is 'F'								*/
14
#define FBIOGET_VSCREENINFO	0x4600
31
#define FBIOGET_VSCREENINFO	0x4600
Lines 36-41 Link Here
36
#define FBIOGET_DISPINFO        0x4618
53
#define FBIOGET_DISPINFO        0x4618
37
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
54
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
38
55
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 length 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 */
74
39
#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
75
#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
40
#define FB_TYPE_PLANES			1	/* Non interleaved planes */
76
#define FB_TYPE_PLANES			1	/* Non interleaved planes */
41
#define FB_TYPE_INTERLEAVED_PLANES	2	/* Interleaved planes	*/
77
#define FB_TYPE_INTERLEAVED_PLANES	2	/* Interleaved planes	*/
Lines 278-283 Link Here
278
	__u32 reserved[4];		/* Reserved for future compatibility */
314
	__u32 reserved[4];		/* Reserved for future compatibility */
279
};
315
};
280
316
317
#ifdef __KERNEL__
318
#ifdef CONFIG_COMPAT
319
struct fb_cmap32 {
320
	__u32 start;
321
	__u32 len;			/* Number of entries */
322
	compat_uptr_t red;		/* Red values	*/
323
	compat_uptr_t green;
324
	compat_uptr_t blue;
325
	compat_uptr_t transp;		/* transparency, can be NULL */
326
};
327
328
#define fb_cmap_from_compat(to, from) \
329
	(to).start  = (from).start; \
330
	(to).len    = (from).len; \
331
	(to).red    = compat_ptr((from).red); \
332
	(to).green  = compat_ptr((from).green); \
333
	(to).blue   = compat_ptr((from).blue); \
334
	(to).transp = compat_ptr((from).transp)
335
336
#endif /* CONFIG_COMPAT */
337
#endif /* __KERNEL__ */
338
339
281
struct fb_cmap {
340
struct fb_cmap {
282
	__u32 start;			/* First entry	*/
341
	__u32 start;			/* First entry	*/
283
	__u32 len;			/* Number of entries */
342
	__u32 len;			/* Number of entries */
(-)linux-4.20.3-gentoo/kernel/sysctl.c (+13 lines)
Lines 154-159 Link Here
154
static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
154
static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
155
#endif
155
#endif
156
156
157
#ifdef CONFIG_FB_CON_DECOR
158
extern char fbcon_decor_path[];
159
#endif
160
157
#ifdef CONFIG_INOTIFY_USER
161
#ifdef CONFIG_INOTIFY_USER
158
#include <linux/inotify.h>
162
#include <linux/inotify.h>
159
#endif
163
#endif
Lines 298-303 Link Here
298
		.mode		= 0555,
302
		.mode		= 0555,
299
		.child		= dev_table,
303
		.child		= dev_table,
300
	},
304
	},
305
#ifdef CONFIG_FB_CON_DECOR
306
	{
307
		.procname	= "fbcondecor",
308
		.data		= &fbcon_decor_path,
309
		.maxlen		= KMOD_PATH_LEN,
310
		.mode		= 0644,
311
		.proc_handler	= &proc_dostring,
312
	},
313
#endif
301
	{ }
314
	{ }
302
};
315
};
303
316

Return to bug 676136