source: npl/kernel/linux_src/4200_fbcondecor.patch

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

upgrade to linux kernel 4.14.172

  • Property mode set to 100644
File size: 60.3 KB
  • Documentation/fb/00-INDEX

    diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
    index fe85e7c5907a..22309308ba56 100644
    a b ep93xx-fb.txt 
    2323        - info on the driver for EP93xx LCD controller.
    2424fbcon.txt
    2525        - intro to and usage guide for the framebuffer console (fbcon).
     26fbcondecor.txt
     27        - info on the Framebuffer Console Decoration
    2628framebuffer.txt
    2729        - introduction to frame buffer devices.
    2830gxfb.txt
  • new file Documentation/fb/fbcondecor.txt

    diff --git a/Documentation/fb/fbcondecor.txt b/Documentation/fb/fbcondecor.txt
    new file mode 100644
    index 000000000000..637209e11ccd
    - +  
     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
  • drivers/Makefile

    diff --git a/drivers/Makefile b/drivers/Makefile
    index 1d034b680431..9f41f2ea0c8b 100644
    a b obj-y += pci/dwc/ 
    2323
    2424obj-$(CONFIG_PARISC)            += parisc/
    2525obj-$(CONFIG_RAPIDIO)           += rapidio/
     26# tty/ comes before char/ so that the VT console is the boot-time
     27# default.
     28obj-y                           += tty/
     29obj-y                           += char/
    2630obj-y                           += video/
    2731obj-y                           += idle/
    2832
    obj-$(CONFIG_REGULATOR) += regulator/ 
    5357# reset controllers early, since gpu drivers might rely on them to initialize
    5458obj-$(CONFIG_RESET_CONTROLLER)  += reset/
    5559
    56 # tty/ comes before char/ so that the VT console is the boot-time
    57 # default.
    58 obj-y                           += tty/
    59 obj-y                           += char/
    60 
    6160# iommu/ comes before gpu as gpu are using iommu controllers
    6261obj-$(CONFIG_IOMMU_SUPPORT)     += iommu/
    6362
  • drivers/video/console/Kconfig

    diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
    index 7f1f1fbcef9e..8439b618dfc0 100644
    a b config FRAMEBUFFER_CONSOLE_ROTATION 
    151151         such that other users of the framebuffer will remain normally
    152152         oriented.
    153153
     154config FB_CON_DECOR
     155        bool "Support for the Framebuffer Console Decorations"
     156        depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
     157        default n
     158        ---help---
     159          This option enables support for framebuffer console decorations which
     160          makes it possible to display images in the background of the system
     161          consoles.  Note that userspace utilities are necessary in order to take
     162          advantage of these features. Refer to Documentation/fb/fbcondecor.txt
     163          for more information.
     164
     165          If unsure, say N.
     166
    154167config STI_CONSOLE
    155168        bool "STI text console"
    156169        depends on PARISC
  • drivers/video/console/Makefile

    diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
    index db07b784bd2c..3e369bd120b8 100644
    a b obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o 
    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
  • new file drivers/video/console/cfbcondecor.c

    diff --git a/drivers/video/console/cfbcondecor.c b/drivers/video/console/cfbcondecor.c
    new file mode 100644
    index 000000000000..b00960803edc
    - +  
     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
  • new file drivers/video/console/fbcondecor.c

    diff --git a/drivers/video/console/fbcondecor.c b/drivers/video/console/fbcondecor.c
    new file mode 100644
    index 000000000000..78288a497a60
    - +  
     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(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
     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(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
     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}
  • new file drivers/video/console/fbcondecor.h

    diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h
    new file mode 100644
    index 000000000000..c49386c16695
    - +  
     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 */
  • drivers/video/fbdev/Kconfig

    diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
    index 5e58f5ec0a28..1daa8c2cb2d8 100644
    a b config FB_MATROX 
    12261226        select FB_CFB_FILLRECT
    12271227        select FB_CFB_COPYAREA
    12281228        select FB_CFB_IMAGEBLIT
    1229         select FB_TILEBLITTING
    12301229        select FB_MACMODES if PPC_PMAC
    12311230        ---help---
    12321231          Say Y here if you have a Matrox Millennium, Matrox Millennium II,
  • drivers/video/fbdev/core/bitblit.c

    diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
    index 790900d646c0..3f940c93752c 100644
    a b  
    1818#include <linux/console.h>
    1919#include <asm/types.h>
    2020#include "fbcon.h"
     21#include "../../console/fbcondecor.h"
    2122
    2223/*
    2324 * Accelerated handlers.
    static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy, 
    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
    static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, 
    379387        cursor.image.depth = 1;
    380388        cursor.rop = ROP_XOR;
    381389
    382         if (info->fbops->fb_cursor)
    383                 err = info->fbops->fb_cursor(info, &cursor);
     390        if (fbcon_decor_active(info, vc)) {
     391                fbcon_decor_cursor(info, &cursor);
     392        } else {
     393                if (info->fbops->fb_cursor)
     394                        err = info->fbops->fb_cursor(info, &cursor);
    384395
    385         if (err)
    386                 soft_cursor(info, &cursor);
     396                if (err)
     397                        soft_cursor(info, &cursor);
     398        }
    387399
    388400        ops->cursor_reset = 0;
    389401}
  • drivers/video/fbdev/core/fbcmap.c

    diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
    index 68a113594808..21f977cb59d2 100644
    a b  
    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};
    int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) 
    256258                                break;
    257259                }
    258260        }
    259         if (rc == 0)
     261        if (rc == 0) {
    260262                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        }
    262267        return rc;
    263268}
    264269
  • drivers/video/fbdev/core/fbcon.c

    diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
    index 04612f938bab..95c349200078 100644
    a b  
    8080#include <asm/irq.h>
    8181
    8282#include "fbcon.h"
     83#include "../../console/fbcondecor.h"
    8384
    8485#ifdef FBCONDEBUG
    8586#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
    enum { 
    9596
    9697static struct display fb_display[MAX_NR_CONSOLES];
    9798
    98 static signed char con2fb_map[MAX_NR_CONSOLES];
     99signed char con2fb_map[MAX_NR_CONSOLES];
    99100static signed char con2fb_map_boot[MAX_NR_CONSOLES];
    100101
    101102static int logo_lines;
    static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) 
    282283                !vt_force_oops_output(vc);
    283284}
    284285
    285 static int get_color(struct vc_data *vc, struct fb_info *info,
     286int get_color(struct vc_data *vc, struct fb_info *info,
    286287              u16 c, int is_fg)
    287288{
    288289        int depth = fb_get_color_depth(&info->var, &info->fix);
    static int do_fbcon_takeover(int show_logo) 
    551552                info_idx = -1;
    552553        } else {
    553554                fbcon_has_console_bind = 1;
     555#ifdef CONFIG_FB_CON_DECOR
     556                fbcon_decor_init();
     557#endif
    554558        }
    555559
    556560        return err;
    static const char *fbcon_startup(void) 
    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);
    static void fbcon_init(struct vc_data *vc, int init) 
    10421052        cap = info->flags;
    10431053
    10441054        if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
    1045             (info->fix.type == FB_TYPE_TEXT))
     1055            (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
    10461056                logo = 0;
    10471057
    10481058        if (var_to_display(p, &info->var, info))
    static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, 
    12751285                fbcon_clear_margins(vc, 0);
    12761286        }
    12771287
     1288        if (fbcon_decor_active(info, vc)) {
     1289                fbcon_decor_clear(vc, info, sy, sx, height, width);
     1290                return;
     1291        }
     1292
    12781293        /* Split blits that cross physical y_wrap boundary */
    12791294
    12801295        y_break = p->vrows - p->yscroll;
    static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, 
    12941309        struct display *p = &fb_display[vc->vc_num];
    12951310        struct fbcon_ops *ops = info->fbcon_par;
    12961311
    1297         if (!fbcon_is_inactive(vc, info))
    1298                 ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
    1299                            get_color(vc, info, scr_readw(s), 1),
    1300                            get_color(vc, info, scr_readw(s), 0));
     1312        if (!fbcon_is_inactive(vc, info)) {
     1313
     1314                if (fbcon_decor_active(info, vc))
     1315                        fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
     1316                else
     1317                        ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
     1318                                   get_color(vc, info, scr_readw(s), 1),
     1319                                   get_color(vc, info, scr_readw(s), 0));
     1320        }
    13011321}
    13021322
    13031323static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
    static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) 
    13131333        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
    13141334        struct fbcon_ops *ops = info->fbcon_par;
    13151335
    1316         if (!fbcon_is_inactive(vc, info))
    1317                 ops->clear_margins(vc, info, margin_color, bottom_only);
     1336        if (!fbcon_is_inactive(vc, info)) {
     1337                if (fbcon_decor_active(info, vc))
     1338                        fbcon_decor_clear_margins(vc, info, bottom_only);
     1339                else
     1340                        ops->clear_margins(vc, info, margin_color, bottom_only);
     1341        }
    13181342}
    13191343
    13201344static void fbcon_cursor(struct vc_data *vc, int mode)
    static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, 
    18351859                        count = vc->vc_rows;
    18361860                if (softback_top)
    18371861                        fbcon_softback_note(vc, t, count);
    1838                 if (logo_shown >= 0)
     1862                if (logo_shown >= 0 || fbcon_decor_active(info, vc))
    18391863                        goto redraw_up;
    18401864                switch (p->scrollmode) {
    18411865                case SCROLL_MOVE:
    static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, 
    19281952                        count = vc->vc_rows;
    19291953                if (logo_shown >= 0)
    19301954                        goto redraw_down;
     1955                if (fbcon_decor_active(info, vc))
     1956                        goto redraw_down;
    19311957                switch (p->scrollmode) {
    19321958                case SCROLL_MOVE:
    19331959                        fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
    static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s 
    20762102                }
    20772103                return;
    20782104        }
     2105
     2106        if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
     2107                /* must use slower redraw bmove to keep background pic intact */
     2108                fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
     2109                return;
     2110        }
     2111
    20792112        ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
    20802113                   height, width);
    20812114}
    static int fbcon_resize(struct vc_data *vc, unsigned int width, 
    21462179        var.yres = virt_h * virt_fh;
    21472180        x_diff = info->var.xres - var.xres;
    21482181        y_diff = info->var.yres - var.yres;
    2149         if (x_diff < 0 || x_diff > virt_fw ||
    2150             y_diff < 0 || y_diff > virt_fh) {
     2182        if ((x_diff < 0 || x_diff > virt_fw ||
     2183                y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
    21512184                const struct fb_videomode *mode;
    21522185
    21532186                DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
    static int fbcon_switch(struct vc_data *vc) 
    21832216
    21842217        info = registered_fb[con2fb_map[vc->vc_num]];
    21852218        ops = info->fbcon_par;
     2219        prev_console = ops->currcon;
     2220        if (prev_console != -1)
     2221                old_info = registered_fb[con2fb_map[prev_console]];
     2222
     2223#ifdef CONFIG_FB_CON_DECOR
     2224        if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
     2225                struct vc_data *vc_curr = vc_cons[prev_console].d;
     2226
     2227                if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
     2228                        // Clear the screen to avoid displaying funky colors
     2229                        // during palette updates.
     2230                        memset((u8 *)info->screen_base + info->fix.line_length * info->var.yoffset,
     2231                               0, info->var.yres * info->fix.line_length);
     2232                }
     2233        }
     2234#endif
    21862235
    21872236        if (softback_top) {
    21882237                if (softback_lines)
    static int fbcon_switch(struct vc_data *vc) 
    22012250                logo_shown = FBCON_LOGO_CANSHOW;
    22022251        }
    22032252
    2204         prev_console = ops->currcon;
    2205         if (prev_console != -1)
    2206                 old_info = registered_fb[con2fb_map[prev_console]];
    22072253        /*
    22082254         * FIXME: If we have multiple fbdev's loaded, we need to
    22092255         * update all info->currcon.  Perhaps, we can place this
    static int fbcon_switch(struct vc_data *vc) 
    22472293                        fbcon_del_cursor_timer(old_info);
    22482294        }
    22492295
     2296        if (fbcon_decor_active_vc(vc)) {
     2297                struct vc_data *vc_curr = vc_cons[prev_console].d;
     2298
     2299                if (!vc_curr->vc_decor.theme ||
     2300                        strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
     2301                        (fbcon_decor_active_nores(info, vc_curr) &&
     2302                         !fbcon_decor_active(info, vc_curr))) {
     2303                        fbcon_decor_disable(vc, 0);
     2304                        fbcon_decor_call_helper("modechange", vc->vc_num);
     2305                }
     2306        }
     2307
    22502308        if (fbcon_is_inactive(vc, info) ||
    22512309            ops->blank_state != FB_BLANK_UNBLANK)
    22522310                fbcon_del_cursor_timer(info);
    static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) 
    23552413                }
    23562414        }
    23572415
    2358         if (!fbcon_is_inactive(vc, info)) {
     2416        if (!fbcon_is_inactive(vc, info)) {
    23592417                if (ops->blank_state != blank) {
    23602418                        ops->blank_state = blank;
    23612419                        fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
    23622420                        ops->cursor_flash = (!blank);
    23632421
    2364                         if (!(info->flags & FBINFO_MISC_USEREVENT))
    2365                                 if (fb_blank(info, blank))
    2366                                         fbcon_generic_blank(vc, info, blank);
     2422                        if (!(info->flags & FBINFO_MISC_USEREVENT)) {
     2423                                if (fb_blank(info, blank)) {
     2424                                        if (fbcon_decor_active(info, vc))
     2425                                                fbcon_decor_blank(vc, info, blank);
     2426                                        else
     2427                                                fbcon_generic_blank(vc, info, blank);
     2428                                }
     2429                        }
    23672430                }
    23682431
    23692432                if (!blank)
    static int fbcon_do_set_font(struct vc_data *vc, int w, int h, 
    25462609                set_vc_hi_font(vc, true);
    25472610
    25482611        if (resize) {
     2612                /* reset wrap/pan */
    25492613                int cols, rows;
    25502614
    25512615                cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
    25522616                rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
     2617
     2618                if (fbcon_decor_active(info, vc)) {
     2619                        info->var.xoffset = info->var.yoffset = p->yscroll = 0;
     2620                        cols = vc->vc_decor.twidth;
     2621                        rows = vc->vc_decor.theight;
     2622                }
    25532623                cols /= w;
    25542624                rows /= h;
     2625
    25552626                vc_resize(vc, cols, rows);
     2627
    25562628                if (con_is_visible(vc) && softback_buf)
    25572629                        fbcon_update_softback(vc);
    25582630        } else if (con_is_visible(vc)
    static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table) 
    26812753        int i, j, k, depth;
    26822754        u8 val;
    26832755
    2684         if (fbcon_is_inactive(vc, info))
     2756        if (fbcon_is_inactive(vc, info)
     2757#ifdef CONFIG_FB_CON_DECOR
     2758                        || vc->vc_num != fg_console
     2759#endif
     2760                )
    26852761                return;
    26862762
    26872763        if (!con_is_visible(vc))
    static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table) 
    27072783        } else
    27082784                fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
    27092785
    2710         fb_set_cmap(&palette_cmap, info);
     2786        if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
     2787            info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
     2788
     2789                u16 *red, *green, *blue;
     2790                int minlen = min(min(info->var.red.length, info->var.green.length),
     2791                                     info->var.blue.length);
     2792
     2793                struct fb_cmap cmap = {
     2794                        .start = 0,
     2795                        .len = (1 << minlen),
     2796                        .red = NULL,
     2797                        .green = NULL,
     2798                        .blue = NULL,
     2799                        .transp = NULL
     2800                };
     2801
     2802                red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
     2803
     2804                if (!red)
     2805                        goto out;
     2806
     2807                green = red + 256;
     2808                blue = green + 256;
     2809                cmap.red = red;
     2810                cmap.green = green;
     2811                cmap.blue = blue;
     2812
     2813                for (i = 0; i < cmap.len; i++)
     2814                        red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
     2815
     2816                fb_set_cmap(&cmap, info);
     2817                fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
     2818                kfree(red);
     2819
     2820                return;
     2821
     2822        } else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
     2823                   info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
     2824                fb_set_cmap(&info->bgdecor.cmap, info);
     2825
     2826out:    fb_set_cmap(&palette_cmap, info);
    27112827}
    27122828
    27132829static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
    static void fbcon_modechanged(struct fb_info *info) 
    29323048                rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
    29333049                cols /= vc->vc_font.width;
    29343050                rows /= vc->vc_font.height;
    2935                 vc_resize(vc, cols, rows);
     3051
     3052                if (!fbcon_decor_active_nores(info, vc)) {
     3053                        vc_resize(vc, cols, rows);
     3054                } else {
     3055                        fbcon_decor_disable(vc, 0);
     3056                        fbcon_decor_call_helper("modechange", vc->vc_num);
     3057                }
     3058
    29363059                updatescrollmode(p, info, vc);
    29373060                scrollback_max = 0;
    29383061                scrollback_current = 0;
    static void fbcon_set_all_vcs(struct fb_info *info) 
    29773100                rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
    29783101                cols /= vc->vc_font.width;
    29793102                rows /= vc->vc_font.height;
    2980                 vc_resize(vc, cols, rows);
     3103                if (!fbcon_decor_active_nores(info, vc))
     3104                        vc_resize(vc, cols, rows);
    29813105        }
    29823106
    29833107        if (fg != -1)
    static void fbcon_exit(void) 
    36183742                }
    36193743        }
    36203744
     3745        fbcon_decor_exit();
    36213746        fbcon_has_exited = 1;
    36223747}
    36233748
  • drivers/video/fbdev/core/fbmem.c

    diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
    index f741ba8df01b..b0141433d249 100644
    a b struct fb_fix_screeninfo32 { 
    12531253        u16                     reserved[3];
    12541254};
    12551255
    1256 struct fb_cmap32 {
    1257         u32                     start;
    1258         u32                     len;
    1259         compat_caddr_t  red;
    1260         compat_caddr_t  green;
    1261         compat_caddr_t  blue;
    1262         compat_caddr_t  transp;
    1263 };
    1264 
    12651256static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
    12661257                          unsigned long arg)
    12671258{
  • new file include/linux/console_decor.h

    diff --git a/include/linux/console_decor.h b/include/linux/console_decor.h
    new file mode 100644
    index 000000000000..15143556c2aa
    - +  
     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
  • include/linux/console_struct.h

    diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
    index c0ec478ea5bf..8bfed6b21fc9 100644
    a b struct vt_struct; 
    2121struct uni_pagedir;
    2222
    2323#define NPAR 16
     24#include <linux/console_decor.h>
    2425
    2526/*
    2627 * Example: vc_data of a console that was scrolled 3 lines down.
    struct vc_data { 
    141142        struct uni_pagedir *vc_uni_pagedir;
    142143        struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
    143144        bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
     145
     146        struct vc_decor vc_decor;
    144147        /* additional information is in vt_kern.h */
    145148};
    146149
  • include/linux/fb.h

    diff --git a/include/linux/fb.h b/include/linux/fb.h
    index bc24e48e396d..ad7d182c7545 100644
    a b struct fb_deferred_io { 
    239239};
    240240#endif
    241241
     242#ifdef __KERNEL__
     243#ifdef CONFIG_COMPAT
     244struct 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
    242270/*
    243271 * Frame buffer operations
    244272 *
    struct fb_info { 
    509537#define FBINFO_STATE_SUSPENDED  1
    510538        u32 state;                      /* Hardware state i.e suspend */
    511539        void *fbcon_par;                /* fbcon use-only private area */
     540
     541        struct fb_image bgdecor;
     542
    512543        /* From here on everything is device dependent */
    513544        void *par;
    514545        /* we need the PCI or similar aperture base/size not
  • include/uapi/linux/fb.h

    diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
    index 6cd9b198b7c6..a228440649fa 100644
    a b  
    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   */
    struct fb_var_screeninfo { 
    278314        __u32 reserved[4];              /* Reserved for future compatibility */
    279315};
    280316
     317#ifdef __KERNEL__
     318#ifdef CONFIG_COMPAT
     319struct 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
    281340struct fb_cmap {
    282341        __u32 start;                    /* First entry  */
    283342        __u32 len;                      /* Number of entries */
  • kernel/sysctl.c

    diff --git a/kernel/sysctl.c b/kernel/sysctl.c
    index d9c31bc2eaea..e33ac56cc32a 100644
    a b static const int cap_last_cap = CAP_LAST_CAP; 
    150150static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
    151151#endif
    152152
     153#ifdef CONFIG_FB_CON_DECOR
     154extern char fbcon_decor_path[];
     155#endif
     156
    153157#ifdef CONFIG_INOTIFY_USER
    154158#include <linux/inotify.h>
    155159#endif
    static struct ctl_table sysctl_base_table[] = { 
    283287                .mode           = 0555,
    284288                .child          = dev_table,
    285289        },
     290#ifdef CONFIG_FB_CON_DECOR
     291        {
     292                .procname       = "fbcondecor",
     293                .data           = &fbcon_decor_path,
     294                .maxlen         = KMOD_PATH_LEN,
     295                .mode           = 0644,
     296                .proc_handler   = &proc_dostring,
     297        },
     298#endif
    286299        { }
    287300};
    288301
Note: See TracBrowser for help on using the repository browser.