source: npl/kernel/linux_src/fbcondecor-5.10.patch

Last change on this file was 1ebb340, checked in by Edwin Eefting <edwin@datux.nl>, 4 years ago

kernel 5.10

  • Property mode set to 100644
File size: 59.2 KB
  • .10/Documentation/fb/fbcondecor.txt

    diff -Naur vanilla-5.10/Documentation/fb/fbcondecor.txt linux-5.10/Documentation/fb/fbcondecor.txt
    old new  
     1What is it?
     2-----------
     3
     4The framebuffer decorations are a kernel feature which allows displaying a
     5background picture on selected consoles.
     6
     7What do I need to get it to work?
     8---------------------------------
     9
     10To 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
     16To get fbcondecor operational right after fbcon initialization is finished, you
     17will have to include a theme and the kernel helper into your initramfs image.
     18Please 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
     23The userspace helper
     24--------------------
     25
     26The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the
     27kernel whenever an important event occurs and the kernel needs some kind of
     28job to be carried out. Important events include console switches and video
     29mode switches (the kernel requests background images and configuration
     30parameters for the current console). The fbcondecor helper must be accessible at
     31all times. If it's not, fbcondecor will be switched off automatically.
     32
     33It's possible to set path to the fbcondecor helper by writing it to
     34/proc/sys/kernel/fbcondecor.
     35
     36*****************************************************************************
     37
     38The information below is mostly technical stuff. There's probably no need to
     39read it unless you plan to develop a userspace helper.
     40
     41The fbcondecor protocol
     42-----------------------
     43
     44The fbcondecor protocol defines a communication interface between the kernel and
     45the userspace fbcondecor helper.
     46
     47The 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
     55The userspace helper is responsible for everything else, including parsing
     56configuration files, decompressing the image files whenever the kernel needs
     57it, and communicating with the kernel if necessary.
     58
     59The fbcondecor protocol specifies how communication is done in both ways:
     60kernel->userspace and userspace->helper.
     61
     62Kernel -> Userspace
     63-------------------
     64
     65The kernel communicates with the userspace helper by calling it and specifying
     66the task to be done in a series of arguments.
     67
     68The arguments follow the pattern:
     69<fbcondecor protocol version> <command> <parameters>
     70
     71All commands defined in fbcondecor protocol v2 have the following parameters:
     72 virtual console
     73 framebuffer number
     74 theme
     75
     76Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the
     77framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used.
     78
     79Fbcondecor protocol v2 specifies the following commands:
     80
     81getpic
     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
     88init
     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
     111modechange
     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
     119Userspace -> Kernel
     120-------------------
     121
     122Userspace programs can communicate with fbcondecor via ioctls on the
     123fbcondecor 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
     126The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL
     127when doing the appropriate ioctls. All userspace configuration tools should
     128use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin
     129field when performing ioctls from the kernel helper will most likely result
     130in a console deadlock.
     131
     132FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console
     133semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire
     134the console sem.
     135
     136The framebuffer console decoration provides the following ioctls (all defined in
     137linux/fb.h):
     138
     139FBIOCONDECOR_SETPIC
     140description: loads a background picture for a virtual console
     141argument: struct fbcon_decor_iowrapper*; data: struct fb_image*
     142notes:
     143If called for consoles other than the current foreground one, the picture data
     144will be ignored.
     145
     146If the current virtual console is running in a 8-bpp mode, the cmap substruct
     147of fb_image has to be filled appropriately: start should be set to 16 (first
     14816 colors are reserved for fbcon), len to a value <= 240 and red, green and
     149blue should point to valid cmap data. The transp field is ingored. The fields
     150dx, dy, bg_color, fg_color in fb_image are ignored as well.
     151
     152FBIOCONDECOR_SETCFG
     153description: sets the fbcondecor config for a virtual console
     154argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
     155notes: The structure has to be filled with valid data.
     156
     157FBIOCONDECOR_GETCFG
     158description: gets the fbcondecor config for a virtual console
     159argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
     160
     161FBIOCONDECOR_SETSTATE
     162description: sets the fbcondecor state for a virtual console
     163argument: struct fbcon_decor_iowrapper*; data: unsigned int*
     164          values: 0 = disabled, 1 = enabled.
     165
     166FBIOCONDECOR_GETSTATE
     167description: gets the fbcondecor state for a virtual console
     168argument: struct fbcon_decor_iowrapper*; data: unsigned int*
     169          values: as in FBIOCONDECOR_SETSTATE
     170
     171Info on used structures:
     172
     173Definition of struct vc_decor can be found in linux/console_decor.h. It's
     174heavily commented. Note that the 'theme' field should point to a string
     175no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is
     176performed, the theme field should point to a char buffer of length
     177FBCON_DECOR_THEME_LEN.
     178
     179Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h.
     180The fields in this struct have the following meaning:
     181
     182vc:
     183Virtual console number.
     184
     185origin:
     186Specifies if the ioctl is performed as a response to a kernel request. The
     187fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace
     188programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to
     189avoid console semaphore deadlocks.
     190
     191data:
     192Pointer to a data structure appropriate for the performed ioctl. Type of
     193the data struct is specified in the ioctls description.
     194
     195*****************************************************************************
     196
     197Credit
     198------
     199
     200Original '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
     205Fbcondecor, fbcondecor protocol design, current implementation & docs by:
     206  Michal Januszewski <michalj+fbcondecor@gmail.com>
     207
  • .10/drivers/Makefile

    diff -Naur vanilla-5.10/drivers/Makefile linux-5.10/drivers/Makefile
    old new  
    2020
    2121obj-$(CONFIG_PARISC)            += parisc/
    2222obj-$(CONFIG_RAPIDIO)           += rapidio/
     23# tty/ comes before char/ so that the VT console is the boot-time
     24# default.
     25obj-y                           += tty/
     26obj-y                           += char/
    2327obj-y                           += video/
    2428obj-y                           += idle/
    2529
     
    5155# reset controllers early, since gpu drivers might rely on them to initialize
    5256obj-$(CONFIG_RESET_CONTROLLER)  += reset/
    5357
    54 # tty/ comes before char/ so that the VT console is the boot-time
    55 # default.
    56 obj-y                           += tty/
    57 obj-y                           += char/
    58 
    5958# iommu/ comes before gpu as gpu are using iommu controllers
    6059obj-y                           += iommu/
    6160
  • .10/drivers/video/console/Kconfig

    diff -Naur vanilla-5.10/drivers/video/console/Kconfig linux-5.10/drivers/video/console/Kconfig
    old new  
    115115          by the firmware in place, rather then replacing the contents with a
    116116          black screen as soon as fbcon loads.
    117117
     118config FB_CON_DECOR
     119        bool "Support for the Framebuffer Console Decorations"
     120        depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
     121        default n
     122        help
     123          This option enables support for framebuffer console decorations which
     124          makes it possible to display images in the background of the system
     125          consoles.  Note that userspace utilities are necessary in order to take
     126          advantage of these features. Refer to Documentation/fb/fbcondecor.txt
     127          for more information.
     128
     129          If unsure, say N.
     130
    118131config STI_CONSOLE
    119132        bool "STI text console"
    120133        depends on PARISC && HAS_IOMEM
  • .10/drivers/video/console/Makefile

    diff -Naur vanilla-5.10/drivers/video/console/Makefile linux-5.10/drivers/video/console/Makefile
    old new  
    99obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
    1010obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
    1111
     12obj-$(CONFIG_FB_CON_DECOR)        += fbcondecor.o cfbcondecor.o
    1213obj-$(CONFIG_FB_STI)              += sticore.o
  • .10/drivers/video/console/cfbcondecor.c

    diff -Naur vanilla-5.10/drivers/video/console/cfbcondecor.c linux-5.10/drivers/video/console/cfbcondecor.c
    old new  
     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
     37extern int get_color(struct vc_data *vc, struct fb_info *info,
     38                     u16 c, int is_fg);
     39
     40void 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
     60void 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
     170void 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
     204void 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
     252static 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
     311void 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
     368static 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
     380void 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
     405void 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
     424void 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
     463void 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
  • .10/drivers/video/console/fbcondecor.c

    diff -Naur vanilla-5.10/drivers/video/console/fbcondecor.c linux-5.10/drivers/video/console/fbcondecor.c
    old new  
     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
     45extern signed char con2fb_map[];
     46static int fbcon_decor_enable(struct vc_data *vc);
     47
     48static int initialized;
     49
     50char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
     51EXPORT_SYMBOL(fbcon_decor_path);
     52
     53int 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. */
     82int 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. */
     112static 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
     141static 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
     155static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state)
     156{
     157        *state = vc->vc_decor.state;
     158}
     159
     160static 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
     196static 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
     216static 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
     310out:
     311        if (img->cmap.red)
     312                vfree(img->cmap.red);
     313
     314        if (tmp)
     315                vfree(tmp);
     316        return -ENOMEM;
     317}
     318
     319static 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(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
     396static 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(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
     497static 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
     503static struct miscdevice fbcon_decor_dev = {
     504        .minor = MISC_DYNAMIC_MINOR,
     505        .name = "fbcondecor",
     506        .fops = &fbcon_decor_ops
     507};
     508
     509void 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
     525int 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
     545int fbcon_decor_exit(void)
     546{
     547        fbcon_decor_reset();
     548        return 0;
     549}
  • .10/drivers/video/console/fbcondecor.h

    diff -Naur vanilla-5.10/drivers/video/console/fbcondecor.h linux-5.10/drivers/video/console/fbcondecor.h
    old new  
     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
     18struct fb_cursor;
     19struct fb_info;
     20struct vc_data;
     21
     22#ifdef CONFIG_FB_CON_DECOR
     23/* fbcondecor.c */
     24int fbcon_decor_init(void);
     25int fbcon_decor_exit(void);
     26int fbcon_decor_call_helper(char *cmd, unsigned short cons);
     27int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw);
     28
     29/* cfbcondecor.c */
     30void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
     31void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor);
     32void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
     33void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
     34void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank);
     35void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
     36void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
     37void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
     38
     39/* vt.c */
     40void acquire_console_sem(void);
     41void release_console_sem(void);
     42void 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
     58static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
     59static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
     60static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
     61static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
     62static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
     63static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
     64static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
     65static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
     66static inline int fbcon_decor_call_helper(char *cmd, unsigned short cons) { return 0; }
     67static inline int fbcon_decor_init(void) { return 0; }
     68static inline int fbcon_decor_exit(void) { return 0; }
     69static 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 */
  • .10/drivers/video/fbdev/Kconfig

    diff -Naur vanilla-5.10/drivers/video/fbdev/Kconfig linux-5.10/drivers/video/fbdev/Kconfig
    old new  
    10851085        select FB_CFB_FILLRECT
    10861086        select FB_CFB_COPYAREA
    10871087        select FB_CFB_IMAGEBLIT
    1088         select FB_TILEBLITTING
    10891088        select FB_MACMODES if PPC_PMAC
    10901089        help
    10911090          Say Y here if you have a Matrox Millennium, Matrox Millennium II,
  • .10/drivers/video/fbdev/core/bitblit.c

    diff -Naur vanilla-5.10/drivers/video/fbdev/core/bitblit.c linux-5.10/drivers/video/fbdev/core/bitblit.c
    old new  
    1818#include <linux/console.h>
    1919#include <asm/types.h>
    2020#include "fbcon.h"
     21#include "../../console/fbcondecor.h"
    2122
    2223/*
    2324 * Accelerated handlers.
     
    5556        area.height = height * vc->vc_font.height;
    5657        area.width = width * vc->vc_font.width;
    5758
     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
    5866        info->fbops->fb_copyarea(info, &area);
    5967}
    6068
     
    370378        cursor.image.depth = 1;
    371379        cursor.rop = ROP_XOR;
    372380
    373         if (info->fbops->fb_cursor)
    374                 err = info->fbops->fb_cursor(info, &cursor);
     381        if (fbcon_decor_active(info, vc)) {
     382                fbcon_decor_cursor(info, &cursor);
     383        } else {
     384                if (info->fbops->fb_cursor)
     385                        err = info->fbops->fb_cursor(info, &cursor);
    375386
    376         if (err)
    377                 soft_cursor(info, &cursor);
     387                if (err)
     388                        soft_cursor(info, &cursor);
     389        }
    378390
    379391        ops->cursor_reset = 0;
    380392}
  • .10/drivers/video/fbdev/core/fbcmap.c

    diff -Naur vanilla-5.10/drivers/video/fbdev/core/fbcmap.c linux-5.10/drivers/video/fbdev/core/fbcmap.c
    old new  
    1717#include <linux/slab.h>
    1818#include <linux/uaccess.h>
    1919
     20#include "../../console/fbcondecor.h"
     21
    2022static u16 red2[] __read_mostly = {
    2123    0x0000, 0xaaaa
    2224};
     
    258260                                break;
    259261                }
    260262        }
    261         if (rc == 0)
     263        if (rc == 0) {
    262264                fb_copy_cmap(cmap, &info->cmap);
    263 
     265                if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
     266                    info->fix.visual == FB_VISUAL_DIRECTCOLOR)
     267                        fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
     268        }
    264269        return rc;
    265270}
    266271
  • .10/drivers/video/fbdev/core/fbcon.c

    diff -Naur vanilla-5.10/drivers/video/fbdev/core/fbcon.c linux-5.10/drivers/video/fbdev/core/fbcon.c
    old new  
    8181#include <asm/irq.h>
    8282
    8383#include "fbcon.h"
     84#include "../../console/fbcondecor.h"
    8485
    8586#ifdef FBCONDEBUG
    8687#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
     
    115116
    116117static struct fbcon_display fb_display[MAX_NR_CONSOLES];
    117118
    118 static signed char con2fb_map[MAX_NR_CONSOLES];
     119signed char con2fb_map[MAX_NR_CONSOLES];
    119120static signed char con2fb_map_boot[MAX_NR_CONSOLES];
    120121
    121122static int logo_lines;
     
    296297                vc->vc_mode != KD_TEXT || ops->graphics);
    297298}
    298299
    299 static int get_color(struct vc_data *vc, struct fb_info *info,
     300int get_color(struct vc_data *vc, struct fb_info *info,
    300301              u16 c, int is_fg)
    301302{
    302303        int depth = fb_get_color_depth(&info->var, &info->fix);
     
    566567                info_idx = -1;
    567568        } else {
    568569                fbcon_has_console_bind = 1;
     570#ifdef CONFIG_FB_CON_DECOR
     571                fbcon_decor_init();
     572#endif
    569573        }
    570574
    571575        return err;
     
    10131017        rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
    10141018        cols /= vc->vc_font.width;
    10151019        rows /= vc->vc_font.height;
     1020
     1021        if (fbcon_decor_active(info, vc)) {
     1022                cols = vc->vc_decor.twidth / vc->vc_font.width;
     1023                rows = vc->vc_decor.theight / vc->vc_font.height;
     1024        }
     1025
    10161026        vc_resize(vc, cols, rows);
    10171027
    10181028        DPRINTK("mode:   %s\n", info->fix.id);
     
    10481058                logo_shown = FBCON_LOGO_DONTSHOW;
    10491059
    10501060        if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
    1051             (info->fix.type == FB_TYPE_TEXT))
     1061            (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
    10521062                logo = 0;
    10531063
    10541064        if (var_to_display(p, &info->var, info))
     
    12831293                fbcon_clear_margins(vc, 0);
    12841294        }
    12851295
     1296        if (fbcon_decor_active(info, vc)) {
     1297                fbcon_decor_clear(vc, info, sy, sx, height, width);
     1298                return;
     1299        }
     1300
    12861301        /* Split blits that cross physical y_wrap boundary */
    12871302
    12881303        y_break = p->vrows - p->yscroll;
     
    13021317        struct fbcon_display *p = &fb_display[vc->vc_num];
    13031318        struct fbcon_ops *ops = info->fbcon_par;
    13041319
    1305         if (!fbcon_is_inactive(vc, info))
    1306                 ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
    1307                            get_color(vc, info, scr_readw(s), 1),
    1308                            get_color(vc, info, scr_readw(s), 0));
     1320        if (!fbcon_is_inactive(vc, info)) {
     1321
     1322                if (fbcon_decor_active(info, vc))
     1323                        fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
     1324                else
     1325                        ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
     1326                                   get_color(vc, info, scr_readw(s), 1),
     1327                                   get_color(vc, info, scr_readw(s), 0));
     1328        }
    13091329}
    13101330
    13111331static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
     
    13211341        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
    13221342        struct fbcon_ops *ops = info->fbcon_par;
    13231343
    1324         if (!fbcon_is_inactive(vc, info))
    1325                 ops->clear_margins(vc, info, margin_color, bottom_only);
     1344        if (!fbcon_is_inactive(vc, info)) {
     1345                if (fbcon_decor_active(info, vc))
     1346                        fbcon_decor_clear_margins(vc, info, bottom_only);
     1347                else
     1348                        ops->clear_margins(vc, info, margin_color, bottom_only);
     1349        }
    13261350}
    13271351
    13281352static void fbcon_cursor(struct vc_data *vc, int mode)
     
    17121736        case SM_UP:
    17131737                if (count > vc->vc_rows)        /* Maximum realistic size */
    17141738                        count = vc->vc_rows;
    1715                 if (logo_shown >= 0)
     1739                if (logo_shown >= 0 || fbcon_decor_active(info, vc))
    17161740                        goto redraw_up;
    17171741                switch (p->scrollmode) {
    17181742                case SCROLL_MOVE:
     
    18041828                        count = vc->vc_rows;
    18051829                if (logo_shown >= 0)
    18061830                        goto redraw_down;
     1831                if (fbcon_decor_active(info, vc))
     1832                        goto redraw_down;
    18071833                switch (p->scrollmode) {
    18081834                case SCROLL_MOVE:
    18091835                        fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
     
    19511977                }
    19521978                return;
    19531979        }
     1980
     1981        if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
     1982                /* must use slower redraw bmove to keep background pic intact */
     1983                fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
     1984                return;
     1985        }
     1986
    19541987        ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
    19551988                   height, width);
    19561989}
     
    20422075        var.yres = virt_h * virt_fh;
    20432076        x_diff = info->var.xres - var.xres;
    20442077        y_diff = info->var.yres - var.yres;
    2045         if (x_diff < 0 || x_diff > virt_fw ||
    2046             y_diff < 0 || y_diff > virt_fh) {
     2078        if ((x_diff < 0 || x_diff > virt_fw ||
     2079                y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
    20472080                const struct fb_videomode *mode;
    20482081
    20492082                DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
     
    20792112
    20802113        info = registered_fb[con2fb_map[vc->vc_num]];
    20812114        ops = info->fbcon_par;
     2115        prev_console = ops->currcon;
     2116        if (prev_console != -1)
     2117                old_info = registered_fb[con2fb_map[prev_console]];
     2118
     2119#ifdef CONFIG_FB_CON_DECOR
     2120        if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
     2121                struct vc_data *vc_curr = vc_cons[prev_console].d;
     2122
     2123                if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
     2124                        // Clear the screen to avoid displaying funky colors
     2125                        // during palette updates.
     2126                        memset((u8 *)info->screen_base + info->fix.line_length * info->var.yoffset,
     2127                               0, info->var.yres * info->fix.line_length);
     2128                }
     2129        }
     2130#endif
    20822131
    20832132        if (logo_shown >= 0) {
    20842133                struct vc_data *conp2 = vc_cons[logo_shown].d;
     
    20892138                logo_shown = FBCON_LOGO_CANSHOW;
    20902139        }
    20912140
    2092         prev_console = ops->currcon;
    2093         if (prev_console != -1)
    2094                 old_info = registered_fb[con2fb_map[prev_console]];
    20952141        /*
    20962142         * FIXME: If we have multiple fbdev's loaded, we need to
    20972143         * update all info->currcon.  Perhaps, we can place this
     
    21352181                        fbcon_del_cursor_timer(old_info);
    21362182        }
    21372183
     2184        if (fbcon_decor_active_vc(vc)) {
     2185                struct vc_data *vc_curr = vc_cons[prev_console].d;
     2186
     2187                if (!vc_curr->vc_decor.theme ||
     2188                        strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
     2189                        (fbcon_decor_active_nores(info, vc_curr) &&
     2190                         !fbcon_decor_active(info, vc_curr))) {
     2191                        fbcon_decor_disable(vc, 0);
     2192                        fbcon_decor_call_helper("modechange", vc->vc_num);
     2193                }
     2194        }
     2195
    21382196        if (fbcon_is_inactive(vc, info) ||
    21392197            ops->blank_state != FB_BLANK_UNBLANK)
    21402198                fbcon_del_cursor_timer(info);
     
    22342292                }
    22352293        }
    22362294
    2237         if (!fbcon_is_inactive(vc, info)) {
     2295        if (!fbcon_is_inactive(vc, info)) {
    22382296                if (ops->blank_state != blank) {
    22392297                        ops->blank_state = blank;
    22402298                        fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
    22412299                        ops->cursor_flash = (!blank);
    22422300
    2243                         if (fb_blank(info, blank))
    2244                                 fbcon_generic_blank(vc, info, blank);
     2301                        if (fb_blank(info, blank)) {
     2302                                if (fbcon_decor_active(info, vc))
     2303                                        fbcon_decor_blank(vc, info, blank);
     2304                                else
     2305                                        fbcon_generic_blank(vc, info, blank);
     2306                        }
    22452307                }
    22462308
    22472309                if (!blank)
     
    24332495                set_vc_hi_font(vc, true);
    24342496
    24352497        if (resize) {
     2498                /* reset wrap/pan */
    24362499                int cols, rows;
    24372500
    24382501                cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
    24392502                rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
     2503
     2504                if (fbcon_decor_active(info, vc)) {
     2505                        info->var.xoffset = info->var.yoffset = p->yscroll = 0;
     2506                        cols = vc->vc_decor.twidth;
     2507                        rows = vc->vc_decor.theight;
     2508                }
    24402509                cols /= w;
    24412510                rows /= h;
     2511
    24422512                vc_resize(vc, cols, rows);
     2513
    24432514        } else if (con_is_visible(vc)
    24442515                   && vc->vc_mode == KD_TEXT) {
    24452516                fbcon_clear_margins(vc, 0);
     
    25672638        int i, j, k, depth;
    25682639        u8 val;
    25692640
    2570         if (fbcon_is_inactive(vc, info))
     2641        if (fbcon_is_inactive(vc, info)
     2642#ifdef CONFIG_FB_CON_DECOR
     2643                        || vc->vc_num != fg_console
     2644#endif
     2645                )
    25712646                return;
    25722647
    25732648        if (!con_is_visible(vc))
     
    25932668        } else
    25942669                fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
    25952670
    2596         fb_set_cmap(&palette_cmap, info);
     2671        if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
     2672            info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
     2673
     2674                u16 *red, *green, *blue;
     2675                int minlen = min(min(info->var.red.length, info->var.green.length),
     2676                                     info->var.blue.length);
     2677
     2678                struct fb_cmap cmap = {
     2679                        .start = 0,
     2680                        .len = (1 << minlen),
     2681                        .red = NULL,
     2682                        .green = NULL,
     2683                        .blue = NULL,
     2684                        .transp = NULL
     2685                };
     2686
     2687                red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
     2688
     2689                if (!red)
     2690                        goto out;
     2691
     2692                green = red + 256;
     2693                blue = green + 256;
     2694                cmap.red = red;
     2695                cmap.green = green;
     2696                cmap.blue = blue;
     2697
     2698                for (i = 0; i < cmap.len; i++)
     2699                        red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
     2700
     2701                fb_set_cmap(&cmap, info);
     2702                fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
     2703                kfree(red);
     2704
     2705                return;
     2706
     2707        } else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
     2708                   info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
     2709                fb_set_cmap(&info->bgdecor.cmap, info);
     2710
     2711out:    fb_set_cmap(&palette_cmap, info);
    25972712}
    25982713
    25992714static u16 *fbcon_screen_pos(const struct vc_data *vc, int offset)
     
    26912806                rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
    26922807                cols /= vc->vc_font.width;
    26932808                rows /= vc->vc_font.height;
    2694                 vc_resize(vc, cols, rows);
     2809
     2810                if (!fbcon_decor_active_nores(info, vc)) {
     2811                        vc_resize(vc, cols, rows);
     2812                } else {
     2813                        fbcon_decor_disable(vc, 0);
     2814                        fbcon_decor_call_helper("modechange", vc->vc_num);
     2815                }
     2816
    26952817                updatescrollmode(p, info, vc);
    26962818                scrollback_max = 0;
    26972819                scrollback_current = 0;
     
    27342856                rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
    27352857                cols /= vc->vc_font.width;
    27362858                rows /= vc->vc_font.height;
    2737                 vc_resize(vc, cols, rows);
     2859                if (!fbcon_decor_active_nores(info, vc))
     2860                        vc_resize(vc, cols, rows);
    27382861        }
    27392862
    27402863        if (fg != -1)
     
    33833506                                info->queue.func = NULL;
    33843507                }
    33853508        }
     3509        fbcon_decor_exit();
    33863510}
    33873511
    33883512void __init fb_console_init(void)
  • .10/drivers/video/fbdev/core/fbmem.c

    diff -Naur vanilla-5.10/drivers/video/fbdev/core/fbmem.c linux-5.10/drivers/video/fbdev/core/fbmem.c
    old new  
    12031203        u16                     reserved[3];
    12041204};
    12051205
    1206 struct fb_cmap32 {
    1207         u32                     start;
    1208         u32                     len;
    1209         compat_caddr_t  red;
    1210         compat_caddr_t  green;
    1211         compat_caddr_t  blue;
    1212         compat_caddr_t  transp;
    1213 };
    1214 
    12151206static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
    12161207                          unsigned long arg)
    12171208{
  • .10/include/linux/console_decor.h

    diff -Naur vanilla-5.10/include/linux/console_decor.h linux-5.10/include/linux/console_decor.h
    old new  
     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) */
     5struct 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
     17struct 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
  • .10/include/linux/console_struct.h

    diff -Naur vanilla-5.10/include/linux/console_struct.h linux-5.10/include/linux/console_struct.h
    old new  
    2222
    2323#define NPAR 16
    2424#define VC_TABSTOPS_COUNT       256U
     25#include <linux/console_decor.h>
    2526
    2627enum vc_intensity {
    2728        VCI_HALF_BRIGHT,
     
    159160        struct uni_pagedir *vc_uni_pagedir;
    160161        struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
    161162        struct uni_screen *vc_uni_screen;       /* unicode screen content */
     163
     164        struct vc_decor vc_decor;
    162165        /* additional information is in vt_kern.h */
    163166};
    164167
  • .10/include/linux/fb.h

    diff -Naur vanilla-5.10/include/linux/fb.h linux-5.10/include/linux/fb.h
    old new  
    211211};
    212212#endif
    213213
     214#ifdef __KERNEL__
     215#ifdef CONFIG_COMPAT
     216struct fb_image32 {
     217        __u32 dx;                       /* Where to place image */
     218        __u32 dy;
     219        __u32 width;                    /* Size of image */
     220        __u32 height;
     221        __u32 fg_color;                 /* Only used when a mono bitmap */
     222        __u32 bg_color;
     223        __u8  depth;                    /* Depth of the image */
     224        const compat_uptr_t data;       /* Pointer to image data */
     225        struct fb_cmap32 cmap;          /* color map info */
     226};
     227
     228#define fb_image_from_compat(to, from) \
     229        (to).dx       = (from).dx; \
     230        (to).dy       = (from).dy; \
     231        (to).width    = (from).width; \
     232        (to).height   = (from).height; \
     233        (to).fg_color = (from).fg_color; \
     234        (to).bg_color = (from).bg_color; \
     235        (to).depth    = (from).depth; \
     236        (to).data     = compat_ptr((from).data); \
     237        fb_cmap_from_compat((to).cmap, (from).cmap)
     238
     239#endif /* CONFIG_COMPAT */
     240#endif /* __KERNEL__ */
     241
    214242/*
    215243 * Frame buffer operations
    216244 *
     
    487515#define FBINFO_STATE_SUSPENDED  1
    488516        u32 state;                      /* Hardware state i.e suspend */
    489517        void *fbcon_par;                /* fbcon use-only private area */
     518
     519        struct fb_image bgdecor;
     520
    490521        /* From here on everything is device dependent */
    491522        void *par;
    492523        /* we need the PCI or similar aperture base/size not
  • .10/include/uapi/linux/fb.h

    diff -Naur vanilla-5.10/include/uapi/linux/fb.h linux-5.10/include/uapi/linux/fb.h
    old new  
    99
    1010#define FB_MAX                  32      /* sufficient for now */
    1111
     12struct 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>
     21struct 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
    1229/* ioctls
    1330   0x46 is 'F'                                                          */
    1431#define FBIOGET_VSCREENINFO     0x4600
     
    3653#define FBIOGET_DISPINFO        0x4618
    3754#define FBIO_WAITFORVSYNC       _IOW('F', 0x20, __u32)
    3855
     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
    3975#define FB_TYPE_PACKED_PIXELS           0       /* Packed Pixels        */
    4076#define FB_TYPE_PLANES                  1       /* Non interleaved planes */
    4177#define FB_TYPE_INTERLEAVED_PLANES      2       /* Interleaved planes   */
     
    279315        __u32 reserved[4];              /* Reserved for future compatibility */
    280316};
    281317
     318#ifdef __KERNEL__
     319#ifdef CONFIG_COMPAT
     320struct fb_cmap32 {
     321        __u32 start;
     322        __u32 len;                      /* Number of entries */
     323        compat_uptr_t red;              /* Red values   */
     324        compat_uptr_t green;
     325        compat_uptr_t blue;
     326        compat_uptr_t transp;           /* transparency, can be NULL */
     327};
     328
     329#define fb_cmap_from_compat(to, from) \
     330        (to).start  = (from).start; \
     331        (to).len    = (from).len; \
     332        (to).red    = compat_ptr((from).red); \
     333        (to).green  = compat_ptr((from).green); \
     334        (to).blue   = compat_ptr((from).blue); \
     335        (to).transp = compat_ptr((from).transp)
     336
     337#endif /* CONFIG_COMPAT */
     338#endif /* __KERNEL__ */
     339
     340
    282341struct fb_cmap {
    283342        __u32 start;                    /* First entry  */
    284343        __u32 len;                      /* Number of entries */
  • .10/kernel/sysctl.c

    diff -Naur vanilla-5.10/kernel/sysctl.c linux-5.10/kernel/sysctl.c
    old new  
    145145static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
    146146#endif
    147147
     148#ifdef CONFIG_FB_CON_DECOR
     149extern char fbcon_decor_path[];
     150#endif
     151
    148152#ifdef CONFIG_INOTIFY_USER
    149153#include <linux/inotify.h>
    150154#endif
     
    33943398                .mode           = 0555,
    33953399                .child          = dev_table,
    33963400        },
     3401#ifdef CONFIG_FB_CON_DECOR
     3402        {
     3403                .procname       = "fbcondecor",
     3404                .data           = &fbcon_decor_path,
     3405                .maxlen         = KMOD_PATH_LEN,
     3406                .mode           = 0644,
     3407                .proc_handler   = &proc_dostring,
     3408        },
     3409#endif
    33973410        { }
    33983411};
    33993412
Note: See TracBrowser for help on using the repository browser.