iPXE
Functions | Variables
fbcon.c File Reference

Frame buffer console. More...

#include <string.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/ansiesc.h>
#include <ipxe/image.h>
#include <ipxe/pixbuf.h>
#include <ipxe/umalloc.h>
#include <ipxe/console.h>
#include <ipxe/fbcon.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static uint32_t fbcon_colour (struct fbcon *fbcon, uint32_t rgb)
 Calculate raw colour value.
static uint32_t fbcon_ansi_colour (struct fbcon *fbcon, unsigned int ansicol)
 Calculate ANSI font colour.
static void fbcon_set_default_foreground (struct fbcon *fbcon)
 Set default foreground colour.
static void fbcon_set_default_background (struct fbcon *fbcon)
 Set default background colour.
static void fbcon_clear (struct fbcon *fbcon, unsigned int ypos)
 Clear rows of characters.
static void fbcon_store (struct fbcon *fbcon, struct fbcon_text_cell *cell, unsigned int xpos, unsigned int ypos)
 Store character at specified position.
static void fbcon_draw (struct fbcon *fbcon, struct fbcon_text_cell *cell, unsigned int xpos, unsigned int ypos)
 Draw character at specified position.
static void fbcon_redraw (struct fbcon *fbcon)
 Redraw all characters.
static void fbcon_scroll (struct fbcon *fbcon)
 Scroll screen.
static void fbcon_draw_cursor (struct fbcon *fbcon, int show_cursor)
 Draw character at cursor position.
static void fbcon_handle_cup (struct ansiesc_context *ctx, unsigned int count __unused, int params[])
 Handle ANSI CUP (cursor position)
static void fbcon_handle_ed (struct ansiesc_context *ctx, unsigned int count __unused, int params[] __unused)
 Handle ANSI ED (erase in page)
static void fbcon_handle_sgr (struct ansiesc_context *ctx, unsigned int count, int params[])
 Handle ANSI SGR (set graphics rendition)
static void fbcon_handle_dectcem_set (struct ansiesc_context *ctx, unsigned int count __unused, int params[] __unused)
 Handle ANSI DECTCEM set (show cursor)
static void fbcon_handle_dectcem_reset (struct ansiesc_context *ctx, unsigned int count __unused, int params[] __unused)
 Handle ANSI DECTCEM reset (hide cursor)
void fbcon_putchar (struct fbcon *fbcon, int character)
 Print a character to current cursor position.
static int fbcon_picture_init (struct fbcon *fbcon, struct pixel_buffer *pixbuf)
 Initialise background picture.
int fbcon_init (struct fbcon *fbcon, userptr_t start, struct fbcon_geometry *pixel, struct fbcon_colour_map *map, struct fbcon_font *font, struct console_configuration *config)
 Initialise frame buffer console.
void fbcon_fini (struct fbcon *fbcon)
 Finalise frame buffer console.

Variables

static struct ansiesc_handler fbcon_ansiesc_handlers []
 ANSI escape sequence handlers.

Detailed Description

Frame buffer console.

Definition in file fbcon.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static uint32_t fbcon_colour ( struct fbcon fbcon,
uint32_t  rgb 
) [static]

Calculate raw colour value.

Parameters:
fbconFrame buffer console
rgb24-bit RGB value
Return values:
rawRaw colour

Definition at line 50 of file fbcon.c.

References fbcon_colour_map::blue_lsb, fbcon_colour_map::blue_scale, cpu_to_le32, fbcon_colour_map::green_lsb, fbcon_colour_map::green_scale, fbcon::map, fbcon_colour_map::red_lsb, and fbcon_colour_map::red_scale.

Referenced by fbcon_ansi_colour(), fbcon_handle_sgr(), and fbcon_picture_init().

                                                                   {
        struct fbcon_colour_map *map = fbcon->map;
        uint8_t red = ( rgb >> 16 );
        uint8_t green = ( rgb >> 8 );
        uint8_t blue = ( rgb >> 0 );
        uint32_t mapped;

        mapped = ( ( ( red >> map->red_scale ) << map->red_lsb ) |
                   ( ( green >> map->green_scale ) << map->green_lsb ) |
                   ( ( blue >> map->blue_scale ) << map->blue_lsb ) );
        return cpu_to_le32 ( mapped );
}
static uint32_t fbcon_ansi_colour ( struct fbcon fbcon,
unsigned int  ansicol 
) [static]

Calculate ANSI font colour.

Parameters:
fbconFrame buffer console
ansicolANSI colour value (0-based)
Return values:
colourRaw colour

Definition at line 70 of file fbcon.c.

References fbcon_colour().

Referenced by fbcon_handle_sgr(), and fbcon_set_default_foreground().

                                                           {
        uint32_t rgb;

        /* Treat ansicol as 3-bit BGR with intensity 0xaa */
        rgb = ( ( ( ansicol & ( 1 << 0 ) ) ? 0xaa0000 : 0 ) |
                ( ( ansicol & ( 1 << 1 ) ) ? 0x00aa00 : 0 ) |
                ( ( ansicol & ( 1 << 2 ) ) ? 0x0000aa : 0 ) );

        return fbcon_colour ( fbcon, rgb );
}
static void fbcon_set_default_foreground ( struct fbcon fbcon) [static]

Set default foreground colour.

Parameters:
fbconFrame buffer console

Definition at line 87 of file fbcon.c.

References fbcon::bold, fbcon_ansi_colour(), and fbcon::foreground.

Referenced by fbcon_handle_sgr(), and fbcon_init().

                                                                 {

        /* Default to non-bold white foreground */
        fbcon->foreground = fbcon_ansi_colour ( fbcon, 0x7 );
        fbcon->bold = 0;
}
static void fbcon_set_default_background ( struct fbcon fbcon) [static]

Set default background colour.

Parameters:
fbconFrame buffer console

Definition at line 99 of file fbcon.c.

References fbcon::background, and FBCON_TRANSPARENT.

Referenced by fbcon_handle_sgr(), and fbcon_init().

                                                                 {

        /* Default to transparent background */
        fbcon->background = FBCON_TRANSPARENT;
}
static void fbcon_clear ( struct fbcon fbcon,
unsigned int  ypos 
) [static]

Clear rows of characters.

Parameters:
fbconFrame buffer console
yposStarting Y position

Definition at line 111 of file fbcon.c.

References fbcon::background, fbcon::character, copy_to_user(), fbcon_text_cell::foreground, fbcon::foreground, fbcon_geometry::height, offset, fbcon_text::start, fbcon::text, and fbcon_geometry::width.

Referenced by fbcon_handle_ed(), fbcon_init(), and fbcon_scroll().

                                                                   {
        struct fbcon_text_cell cell = {
                .foreground = fbcon->foreground,
                .background = fbcon->background,
                .character = ' ',
        };
        size_t offset;
        unsigned int xpos;

        /* Clear stored character array */
        for ( ; ypos < fbcon->character.height ; ypos++ ) {
                offset = ( ypos * fbcon->character.width * sizeof ( cell ) );
                for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
                        copy_to_user ( fbcon->text.start, offset, &cell,
                                       sizeof ( cell ) );
                        offset += sizeof ( cell );
                }
        }
}
static void fbcon_store ( struct fbcon fbcon,
struct fbcon_text_cell cell,
unsigned int  xpos,
unsigned int  ypos 
) [static]

Store character at specified position.

Parameters:
fbconFrame buffer console
cellText cell
xposX position
yposY position

Definition at line 139 of file fbcon.c.

References fbcon::character, copy_to_user(), offset, fbcon_text::start, fbcon::text, and fbcon_geometry::width.

Referenced by fbcon_putchar().

                                                                 {
        size_t offset;

        /* Store cell */
        offset = ( ( ( ypos * fbcon->character.width ) + xpos ) *
                   sizeof ( *cell ) );
        copy_to_user ( fbcon->text.start, offset, cell, sizeof ( *cell ) );
}
static void fbcon_draw ( struct fbcon fbcon,
struct fbcon_text_cell cell,
unsigned int  xpos,
unsigned int  ypos 
) [static]

Draw character at specified position.

Parameters:
fbconFrame buffer console
cellText cell
xposX position
yposY position

Definition at line 157 of file fbcon.c.

References fbcon_text_cell::background, fbcon_text_cell::character, fbcon::character, column, copy_to_user(), FBCON_CHAR_WIDTH, FBCON_TRANSPARENT, fbcon::font, fbcon_text_cell::foreground, fbcon_font::glyph, fbcon_font::height, fbcon::indent, fbcon_geometry::len, memcpy_user(), memset_user(), offset, fbcon::picture, fbcon::pixel, src, fbcon_picture::start, fbcon::start, and fbcon_geometry::stride.

Referenced by fbcon_draw_cursor(), fbcon_putchar(), and fbcon_redraw().

                                                                {
        uint8_t glyph[fbcon->font->height];
        size_t offset;
        size_t pixel_len;
        size_t skip_len;
        unsigned int row;
        unsigned int column;
        uint8_t bitmask;
        int transparent;
        void *src;

        /* Get font character */
        fbcon->font->glyph ( cell->character, glyph );

        /* Calculate pixel geometry */
        offset = ( fbcon->indent +
                   ( ypos * fbcon->character.stride ) +
                   ( xpos * fbcon->character.len ) );
        pixel_len = fbcon->pixel->len;
        skip_len = ( fbcon->pixel->stride - fbcon->character.len );

        /* Check for transparent background colour */
        transparent = ( cell->background == FBCON_TRANSPARENT );

        /* Draw character rows */
        for ( row = 0 ; row < fbcon->font->height ; row++ ) {

                /* Draw background picture, if applicable */
                if ( transparent ) {
                        if ( fbcon->picture.start ) {
                                memcpy_user ( fbcon->start, offset,
                                              fbcon->picture.start, offset,
                                              fbcon->character.len );
                        } else {
                                memset_user ( fbcon->start, offset, 0,
                                              fbcon->character.len );
                        }
                }

                /* Draw character row */
                for ( column = FBCON_CHAR_WIDTH, bitmask = glyph[row] ;
                      column ; column--, bitmask <<= 1, offset += pixel_len ) {
                        if ( bitmask & 0x80 ) {
                                src = &cell->foreground;
                        } else if ( ! transparent ) {
                                src = &cell->background;
                        } else {
                                continue;
                        }
                        copy_to_user ( fbcon->start, offset, src, pixel_len );
                }

                /* Move to next row */
                offset += skip_len;
        }
}
static void fbcon_redraw ( struct fbcon fbcon) [static]

Redraw all characters.

Parameters:
fbconFrame buffer console

Definition at line 220 of file fbcon.c.

References fbcon::character, copy_from_user(), fbcon_draw(), fbcon_geometry::height, offset, fbcon_text::start, fbcon::text, and fbcon_geometry::width.

Referenced by fbcon_handle_ed(), and fbcon_scroll().

                                                 {
        struct fbcon_text_cell cell;
        size_t offset = 0;
        unsigned int xpos;
        unsigned int ypos;

        /* Redraw characters */
        for ( ypos = 0 ; ypos < fbcon->character.height ; ypos++ ) {
                for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
                        copy_from_user ( &cell, fbcon->text.start, offset,
                                         sizeof ( cell ) );
                        fbcon_draw ( fbcon, &cell, xpos, ypos );
                        offset += sizeof ( cell );
                }
        }
}
static void fbcon_scroll ( struct fbcon fbcon) [static]

Scroll screen.

Parameters:
fbconFrame buffer console

Definition at line 242 of file fbcon.c.

References assert, fbcon::character, fbcon_clear(), fbcon_redraw(), fbcon_geometry::height, memmove_user(), fbcon_text::start, fbcon::text, fbcon_geometry::width, and fbcon::ypos.

Referenced by fbcon_putchar().

                                                 {
        size_t row_len;

        /* Sanity check */
        assert ( fbcon->ypos == fbcon->character.height );

        /* Scroll up character array */
        row_len = ( fbcon->character.width * sizeof ( struct fbcon_text_cell ));
        memmove_user ( fbcon->text.start, 0, fbcon->text.start, row_len,
                       ( row_len * ( fbcon->character.height - 1 ) ) );
        fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) );

        /* Update cursor position */
        fbcon->ypos--;

        /* Redraw all characters */
        fbcon_redraw ( fbcon );
}
static void fbcon_draw_cursor ( struct fbcon fbcon,
int  show_cursor 
) [static]

Draw character at cursor position.

Parameters:
fbconFrame buffer console
show_cursorShow cursor

Definition at line 267 of file fbcon.c.

References fbcon_text_cell::background, fbcon::background, fbcon::character, copy_from_user(), fbcon_draw(), FBCON_TRANSPARENT, fbcon_text_cell::foreground, fbcon::foreground, offset, fbcon_text::start, fbcon::text, fbcon_geometry::width, fbcon::xpos, and fbcon::ypos.

Referenced by fbcon_handle_cup(), fbcon_handle_dectcem_reset(), fbcon_handle_dectcem_set(), fbcon_handle_ed(), and fbcon_putchar().

                                                                       {
        struct fbcon_text_cell cell;
        size_t offset;

        offset = ( ( ( fbcon->ypos * fbcon->character.width ) + fbcon->xpos ) *
                   sizeof ( cell ) );
        copy_from_user ( &cell, fbcon->text.start, offset, sizeof ( cell ) );
        if ( show_cursor ) {
                cell.background = fbcon->foreground;
                cell.foreground = ( ( fbcon->background == FBCON_TRANSPARENT ) ?
                                    0 : fbcon->background );
        }
        fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
}
static void fbcon_handle_cup ( struct ansiesc_context ctx,
unsigned int count  __unused,
int  params[] 
) [static]

Handle ANSI CUP (cursor position)

Parameters:
ctxANSI escape sequence context
countParameter count
params[0]Row (1 is top)
params[1]Column (1 is left)

Definition at line 290 of file fbcon.c.

References fbcon::character, container_of, cx, fbcon_draw_cursor(), fbcon_geometry::height, fbcon::show_cursor, fbcon_geometry::width, fbcon::xpos, and fbcon::ypos.

                                                                           {
        struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
        int cx = ( params[1] - 1 );
        int cy = ( params[0] - 1 );

        fbcon_draw_cursor ( fbcon, 0 );
        fbcon->xpos = cx;
        if ( fbcon->xpos >= fbcon->character.width )
                fbcon->xpos = 0;
        fbcon->ypos = cy;
        if ( fbcon->ypos >= fbcon->character.height )
                fbcon->ypos = 0;
        fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
}
static void fbcon_handle_ed ( struct ansiesc_context ctx,
unsigned int count  __unused,
int params[]  __unused 
) [static]

Handle ANSI ED (erase in page)

Parameters:
ctxANSI escape sequence context
countParameter count
params[0]Region to erase

Definition at line 313 of file fbcon.c.

References ANSIESC_ED_ALL, assert, container_of, fbcon_clear(), fbcon_draw_cursor(), fbcon_redraw(), params, fbcon::show_cursor, fbcon::xpos, and fbcon::ypos.

                                                      {
        struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );

        /* We assume that we always clear the whole screen */
        assert ( params[0] == ANSIESC_ED_ALL );

        /* Clear character array */
        fbcon_clear ( fbcon, 0 );

        /* Redraw all characters */
        fbcon_redraw ( fbcon );

        /* Reset cursor position */
        fbcon->xpos = 0;
        fbcon->ypos = 0;
        fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
}
static void fbcon_handle_sgr ( struct ansiesc_context ctx,
unsigned int  count,
int  params[] 
) [static]

Handle ANSI SGR (set graphics rendition)

Parameters:
ctxANSI escape sequence context
countParameter count
paramsList of graphic rendition aspects

Definition at line 340 of file fbcon.c.

References fbcon::background, fbcon::bold, container_of, count, end, fbcon_ansi_colour(), FBCON_BOLD, fbcon_colour(), fbcon_set_default_background(), fbcon_set_default_foreground(), fbcon::foreground, and NULL.

                                              {
        struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
        uint32_t *custom = NULL;
        uint32_t rgb;
        unsigned int end;
        unsigned int i;
        int aspect;

        for ( i = 0 ; i < count ; i++ ) {

                /* Process aspect */
                aspect = params[i];
                if ( aspect == 0 ) {
                        fbcon_set_default_foreground ( fbcon );
                        fbcon_set_default_background ( fbcon );
                } else if ( aspect == 1 ) {
                        fbcon->bold = fbcon_colour ( fbcon, FBCON_BOLD );
                } else if ( aspect == 22 ) {
                        fbcon->bold = 0;
                } else if ( ( aspect >= 30 ) && ( aspect <= 37 ) ) {
                        fbcon->foreground =
                                fbcon_ansi_colour ( fbcon, aspect - 30 );
                } else if ( aspect == 38 ) {
                        custom = &fbcon->foreground;
                } else if ( aspect == 39 ) {
                        fbcon_set_default_foreground ( fbcon );
                } else if ( ( aspect >= 40 ) && ( aspect <= 47 ) ) {
                        fbcon->background =
                                fbcon_ansi_colour ( fbcon, aspect - 40 );
                } else if ( aspect == 48 ) {
                        custom = &fbcon->background;
                } else if ( aspect == 49 ) {
                        fbcon_set_default_background ( fbcon );
                }

                /* Process custom RGB colour, if applicable
                 *
                 * We support the xterm-compatible
                 * "<ESC>[38;2;<red>;<green>;<blue>m" and
                 * "<ESC>[48;2;<red>;<green>;<blue>m" sequences.
                 */
                if ( custom ) {
                        rgb = 0;
                        end = ( i + 5 );
                        for ( ; ( i < count ) && ( i < end ) ; i++ )
                                rgb = ( ( rgb << 8 ) | params[i] );
                        *custom = fbcon_colour ( fbcon, rgb );
                        custom = NULL;
                }
        }
}
static void fbcon_handle_dectcem_set ( struct ansiesc_context ctx,
unsigned int count  __unused,
int params[]  __unused 
) [static]

Handle ANSI DECTCEM set (show cursor)

Parameters:
ctxANSI escape sequence context
countParameter count
paramsList of graphic rendition aspects

Definition at line 400 of file fbcon.c.

References container_of, fbcon_draw_cursor(), and fbcon::show_cursor.

                                                               {
        struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );

        fbcon->show_cursor = 1;
        fbcon_draw_cursor ( fbcon, 1 );
}
static void fbcon_handle_dectcem_reset ( struct ansiesc_context ctx,
unsigned int count  __unused,
int params[]  __unused 
) [static]

Handle ANSI DECTCEM reset (hide cursor)

Parameters:
ctxANSI escape sequence context
countParameter count
paramsList of graphic rendition aspects

Definition at line 416 of file fbcon.c.

References container_of, fbcon_draw_cursor(), and fbcon::show_cursor.

                                                                 {
        struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );

        fbcon->show_cursor = 0;
        fbcon_draw_cursor ( fbcon, 0 );
}
void fbcon_putchar ( struct fbcon fbcon,
int  character 
)

Print a character to current cursor position.

Parameters:
fbconFrame buffer console
characterCharacter

Definition at line 441 of file fbcon.c.

References ansiesc_process(), fbcon_text_cell::background, fbcon::background, fbcon::bold, fbcon_text_cell::character, fbcon::character, fbcon::ctx, fbcon_draw(), fbcon_draw_cursor(), fbcon_scroll(), fbcon_store(), fbcon_text_cell::foreground, fbcon::foreground, fbcon_geometry::height, fbcon::show_cursor, fbcon_geometry::width, fbcon::xpos, and fbcon::ypos.

Referenced by efifb_putchar(), and vesafb_putchar().

                                                          {
        struct fbcon_text_cell cell;

        /* Intercept ANSI escape sequences */
        character = ansiesc_process ( &fbcon->ctx, character );
        if ( character < 0 )
                return;

        /* Handle control characters */
        switch ( character ) {
        case '\r':
                fbcon_draw_cursor ( fbcon, 0 );
                fbcon->xpos = 0;
                break;
        case '\n':
                fbcon_draw_cursor ( fbcon, 0 );
                fbcon->xpos = 0;
                fbcon->ypos++;
                break;
        case '\b':
                fbcon_draw_cursor ( fbcon, 0 );
                if ( fbcon->xpos ) {
                        fbcon->xpos--;
                } else if ( fbcon->ypos ) {
                        fbcon->xpos = ( fbcon->character.width - 1 );
                        fbcon->ypos--;
                }
                break;
        default:
                /* Print character at current cursor position */
                cell.foreground = ( fbcon->foreground | fbcon->bold );
                cell.background = fbcon->background;
                cell.character = character;
                fbcon_store ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
                fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );

                /* Advance cursor */
                fbcon->xpos++;
                if ( fbcon->xpos >= fbcon->character.width ) {
                        fbcon->xpos = 0;
                        fbcon->ypos++;
                }
                break;
        }

        /* Scroll screen if necessary */
        if ( fbcon->ypos >= fbcon->character.height )
                fbcon_scroll ( fbcon );

        /* Show cursor */
        fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
}
static int fbcon_picture_init ( struct fbcon fbcon,
struct pixel_buffer pixbuf 
) [static]

Initialise background picture.

Parameters:
fbconFrame buffer console
pixbufBackground picture
Return values:
rcReturn status code

Definition at line 501 of file fbcon.c.

References copy_from_user(), copy_to_user(), pixel_buffer::data, DBGC, ENOMEM, fbcon_colour(), pixel_buffer::height, fbcon_geometry::height, fbcon_geometry::len, len, memset_user(), offset, fbcon::picture, fbcon::pixel, raw, rc, fbcon_picture::start, fbcon_geometry::stride, ufree(), umalloc(), pixel_buffer::width, and fbcon_geometry::width.

Referenced by fbcon_init().

                                                              {
        struct fbcon_geometry *pixel = fbcon->pixel;
        struct fbcon_picture *picture = &fbcon->picture;
        size_t len;
        size_t pixbuf_stride;
        size_t indent;
        size_t pixbuf_indent;
        size_t offset;
        size_t pixbuf_offset;
        uint32_t rgb;
        uint32_t raw;
        unsigned int x;
        unsigned int y;
        unsigned int width;
        unsigned int height;
        int xgap;
        int ygap;
        int rc;

        /* Allocate buffer */
        len = ( pixel->height * pixel->stride );
        picture->start = umalloc ( len );
        if ( ! picture->start ) {
                DBGC ( fbcon, "FBCON %p could not allocate %zd bytes for "
                       "picture\n", fbcon, len );
                rc = -ENOMEM;
                goto err_umalloc;
        }

        /* Centre picture on console */
        pixbuf_stride = ( pixbuf->width * sizeof ( rgb ) );
        xgap = ( ( ( int ) ( pixel->width - pixbuf->width ) ) / 2 );
        ygap = ( ( ( int ) ( pixel->height - pixbuf->height ) ) / 2 );
        indent = ( ( ( ( ygap >= 0 ) ? ygap : 0 ) * pixel->stride ) +
                   ( ( ( xgap >= 0 ) ? xgap : 0 ) * pixel->len ) );
        pixbuf_indent = ( ( ( ( ygap < 0 ) ? -ygap : 0 ) * pixbuf_stride ) +
                          ( ( ( xgap < 0 ) ? -xgap : 0 ) * sizeof ( rgb ) ) );
        width = pixbuf->width;
        if ( width > pixel->width )
                width = pixel->width;
        height = pixbuf->height;
        if ( height > pixel->height )
                height = pixel->height;
        DBGC ( fbcon, "FBCON %p picture is pixel %dx%d at [%d,%d),[%d,%d)\n",
               fbcon, width, height, xgap, ( xgap + pixbuf->width ), ygap,
               ( ygap + pixbuf->height ) );

        /* Convert to frame buffer raw format */
        memset_user ( picture->start, 0, 0, len );
        for ( y = 0 ; y < height ; y++ ) {
                offset = ( indent + ( y * pixel->stride ) );
                pixbuf_offset = ( pixbuf_indent + ( y * pixbuf_stride ) );
                for ( x = 0 ; x < width ; x++ ) {
                        copy_from_user ( &rgb, pixbuf->data, pixbuf_offset,
                                         sizeof ( rgb ) );
                        raw = fbcon_colour ( fbcon, rgb );
                        copy_to_user ( picture->start, offset, &raw,
                                       pixel->len );
                        offset += pixel->len;
                        pixbuf_offset += sizeof ( rgb );
                }
        }

        return 0;

        ufree ( picture->start );
 err_umalloc:
        return rc;
}
int fbcon_init ( struct fbcon fbcon,
userptr_t  start,
struct fbcon_geometry pixel,
struct fbcon_colour_map map,
struct fbcon_font font,
struct console_configuration config 
)

Initialise frame buffer console.

Parameters:
fbconFrame buffer console
startStart address
pixelPixel geometry
mapColour mapping
fontFont definition
configConsole configuration
Return values:
rcReturn status code

Definition at line 583 of file fbcon.c.

References assert, console_configuration::bottom, bottom, fbcon_margin::bottom, fbcon::character, console_set_size(), fbcon::ctx, DBGC, EINVAL, ENOMEM, fbcon_ansiesc_handlers, FBCON_CHAR_WIDTH, fbcon_clear(), fbcon_picture_init(), fbcon_set_default_background(), fbcon_set_default_foreground(), fbcon::font, ansiesc_context::handlers, console_configuration::height, fbcon_font::height, fbcon_geometry::height, fbcon::indent, console_configuration::left, fbcon_margin::left, fbcon_geometry::len, fbcon::len, fbcon::map, fbcon::margin, memcpy_user(), memset(), memset_user(), fbcon::picture, console_configuration::pixbuf, fbcon::pixel, rc, console_configuration::right, fbcon_margin::right, fbcon::show_cursor, fbcon_text::start, fbcon_picture::start, fbcon::start, start, fbcon_geometry::stride, fbcon::text, console_configuration::top, top, fbcon_margin::top, ufree(), umalloc(), user_to_phys(), console_configuration::width, and fbcon_geometry::width.

Referenced by efifb_init(), and vesafb_init().

                                                        {
        int width;
        int height;
        unsigned int xgap;
        unsigned int ygap;
        unsigned int left;
        unsigned int right;
        unsigned int top;
        unsigned int bottom;
        int rc;

        /* Initialise data structure */
        memset ( fbcon, 0, sizeof ( *fbcon ) );
        fbcon->start = start;
        fbcon->pixel = pixel;
        assert ( pixel->len <= sizeof ( uint32_t ) );
        fbcon->map = map;
        fbcon->font = font;
        fbcon->ctx.handlers = fbcon_ansiesc_handlers;
        fbcon->show_cursor = 1;

        /* Derive overall length */
        fbcon->len = ( pixel->height * pixel->stride );
        DBGC ( fbcon, "FBCON %p at [%08lx,%08lx)\n", fbcon,
               user_to_phys ( fbcon->start, 0 ),
               user_to_phys ( fbcon->start, fbcon->len ) );

        /* Calculate margin.  If the actual screen size is larger than
         * the requested screen size, then update the margins so that
         * the margin remains relative to the requested screen size.
         * (As an exception, if a zero margin was specified then treat
         * this as meaning "expand to edge of actual screen".)
         */
        xgap = ( pixel->width - config->width );
        ygap = ( pixel->height - config->height );
        left = ( xgap / 2 );
        right = ( xgap - left );
        top = ( ygap / 2 );
        bottom = ( ygap - top );
        fbcon->margin.left = ( config->left + ( config->left ? left : 0 ) );
        fbcon->margin.right = ( config->right + ( config->right ? right : 0 ) );
        fbcon->margin.top = ( config->top + ( config->top ? top : 0 ) );
        fbcon->margin.bottom =
                ( config->bottom + ( config->bottom ? bottom : 0 ) );

        /* Expand margin to accommodate whole characters */
        width = ( pixel->width - fbcon->margin.left - fbcon->margin.right );
        height = ( pixel->height - fbcon->margin.top - fbcon->margin.bottom );
        if ( ( width < FBCON_CHAR_WIDTH ) ||
             ( height < ( ( int ) font->height ) ) ) {
                DBGC ( fbcon, "FBCON %p has unusable character area "
                       "[%d-%d),[%d-%d)\n", fbcon, fbcon->margin.left,
                       ( pixel->width - fbcon->margin.right ),
                       fbcon->margin.top,
                       ( pixel->height - fbcon->margin.bottom ) );
                rc = -EINVAL;
                goto err_margin;
        }
        xgap = ( width % FBCON_CHAR_WIDTH );
        ygap = ( height % font->height );
        fbcon->margin.left += ( xgap / 2 );
        fbcon->margin.top += ( ygap / 2 );
        fbcon->margin.right += ( xgap - ( xgap / 2 ) );
        fbcon->margin.bottom += ( ygap - ( ygap / 2 ) );
        fbcon->indent = ( ( fbcon->margin.top * pixel->stride ) +
                          ( fbcon->margin.left * pixel->len ) );

        /* Derive character geometry from pixel geometry */
        fbcon->character.width = ( width / FBCON_CHAR_WIDTH );
        fbcon->character.height = ( height / font->height );
        fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH );
        fbcon->character.stride = ( pixel->stride * font->height );
        DBGC ( fbcon, "FBCON %p is pixel %dx%d, char %dx%d at "
               "[%d-%d),[%d-%d)\n", fbcon, fbcon->pixel->width,
               fbcon->pixel->height, fbcon->character.width,
               fbcon->character.height, fbcon->margin.left,
               ( fbcon->pixel->width - fbcon->margin.right ),
               fbcon->margin.top,
               ( fbcon->pixel->height - fbcon->margin.bottom ) );

        /* Set default colours */
        fbcon_set_default_foreground ( fbcon );
        fbcon_set_default_background ( fbcon );

        /* Allocate and initialise stored character array */
        fbcon->text.start = umalloc ( fbcon->character.width *
                                      fbcon->character.height *
                                      sizeof ( struct fbcon_text_cell ) );
        if ( ! fbcon->text.start ) {
                rc = -ENOMEM;
                goto err_text;
        }
        fbcon_clear ( fbcon, 0 );

        /* Set framebuffer to all black (including margins) */
        memset_user ( fbcon->start, 0, 0, fbcon->len );

        /* Generate pixel buffer from background image, if applicable */
        if ( config->pixbuf &&
             ( ( rc = fbcon_picture_init ( fbcon, config->pixbuf ) ) != 0 ) )
                goto err_picture;

        /* Draw background picture (including margins), if applicable */
        if ( fbcon->picture.start ) {
                memcpy_user ( fbcon->start, 0, fbcon->picture.start, 0,
                              fbcon->len );
        }

        /* Update console width and height */
        console_set_size ( fbcon->character.width, fbcon->character.height );

        return 0;

        ufree ( fbcon->picture.start );
 err_picture:
        ufree ( fbcon->text.start );
 err_text:
 err_margin:
        return rc;
}
void fbcon_fini ( struct fbcon fbcon)

Finalise frame buffer console.

Parameters:
fbconFrame buffer console

Definition at line 713 of file fbcon.c.

References fbcon::picture, fbcon_text::start, fbcon_picture::start, fbcon::text, and ufree().

Referenced by efifb_fini(), efifb_init(), vesafb_fini(), and vesafb_init().

                                        {

        ufree ( fbcon->text.start );
        ufree ( fbcon->picture.start );
}

Variable Documentation

Initial value:

ANSI escape sequence handlers.

Definition at line 426 of file fbcon.c.

Referenced by fbcon_init().