From 608d6cac9eb6df2bf232ce955d81dfba63b9570b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 22 Jan 2014 13:57:07 +0000 Subject: [PATCH] [fbcon] Allow for an arbitrary margin around the text area Signed-off-by: Michael Brown --- src/arch/i386/interface/pcbios/vesafb.c | 6 ++-- src/core/fbcon.c | 41 +++++++++++++++++-------- src/include/ipxe/console.h | 8 +++++ src/include/ipxe/fbcon.h | 1 + 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/arch/i386/interface/pcbios/vesafb.c b/src/arch/i386/interface/pcbios/vesafb.c index 480c9acf..bc2301cc 100644 --- a/src/arch/i386/interface/pcbios/vesafb.c +++ b/src/arch/i386/interface/pcbios/vesafb.c @@ -76,6 +76,8 @@ struct vesafb { physaddr_t start; /** Pixel geometry */ struct fbcon_geometry pixel; + /** Margin */ + struct fbcon_margin margin; /** Colour mapping */ struct fbcon_colour_map map; /** Font definition */ @@ -428,8 +430,8 @@ static int vesafb_init ( unsigned int min_width, unsigned int min_height, /* Initialise frame buffer console */ if ( ( rc = fbcon_init ( &vesafb.fbcon, phys_to_user ( vesafb.start ), - &vesafb.pixel, &vesafb.map, &vesafb.font, - pixbuf ) ) != 0 ) + &vesafb.pixel, &vesafb.margin, &vesafb.map, + &vesafb.font, pixbuf ) ) != 0 ) goto err_fbcon_init; free ( mode_numbers ); diff --git a/src/core/fbcon.c b/src/core/fbcon.c index 72bfae2a..32ae43be 100644 --- a/src/core/fbcon.c +++ b/src/core/fbcon.c @@ -573,6 +573,7 @@ static int fbcon_picture_init ( struct fbcon *fbcon, * @v fbcon Frame buffer console * @v start Start address * @v pixel Pixel geometry + * @v margin Minimum margin * @v map Colour mapping * @v font Font definition * @v pixbuf Background picture (if any) @@ -580,9 +581,12 @@ static int fbcon_picture_init ( struct fbcon *fbcon, */ int fbcon_init ( struct fbcon *fbcon, userptr_t start, struct fbcon_geometry *pixel, + struct fbcon_margin *margin, struct fbcon_colour_map *map, struct fbcon_font *font, struct pixel_buffer *pixbuf ) { + int width; + int height; unsigned int xgap; unsigned int ygap; int rc; @@ -603,21 +607,31 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start, user_to_phys ( fbcon->start, 0 ), user_to_phys ( fbcon->start, fbcon->len ) ); - /* Derive character geometry from pixel geometry */ - fbcon->character.width = ( pixel->width / FBCON_CHAR_WIDTH ); - fbcon->character.height = ( pixel->height / FBCON_CHAR_HEIGHT ); - fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH ); - fbcon->character.stride = ( pixel->stride * FBCON_CHAR_HEIGHT ); - - /* Calculate margin */ - xgap = ( pixel->width % FBCON_CHAR_WIDTH ); - ygap = ( pixel->height % FBCON_CHAR_HEIGHT ); - fbcon->margin.left = ( xgap / 2 ); - fbcon->margin.top = ( ygap / 2 ); - fbcon->margin.right = ( xgap - fbcon->margin.left ); - fbcon->margin.bottom = ( ygap - fbcon->margin.top ); + /* Expand margin to accommodate whole characters */ + width = ( pixel->width - margin->left - margin->right ); + height = ( pixel->height - margin->top - margin->bottom ); + if ( ( width < FBCON_CHAR_WIDTH ) || ( height < FBCON_CHAR_HEIGHT ) ) { + DBGC ( fbcon, "FBCON %p has unusable character area " + "[%d-%d),[%d-%d)\n", fbcon, + margin->left, ( pixel->width - margin->right ), + margin->top, ( pixel->height - margin->bottom ) ); + rc = -EINVAL; + goto err_margin; + } + xgap = ( width % FBCON_CHAR_WIDTH ); + ygap = ( height % FBCON_CHAR_HEIGHT ); + fbcon->margin.left = ( margin->left + ( xgap / 2 ) ); + fbcon->margin.top = ( margin->top + ( ygap / 2 ) ); + fbcon->margin.right = ( margin->right + ( xgap - ( xgap / 2 ) ) ); + fbcon->margin.bottom = ( 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 / FBCON_CHAR_HEIGHT ); + fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH ); + fbcon->character.stride = ( pixel->stride * FBCON_CHAR_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, @@ -662,6 +676,7 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start, err_picture: ufree ( fbcon->text.start ); err_text: + err_margin: return rc; } diff --git a/src/include/ipxe/console.h b/src/include/ipxe/console.h index ab39cbfc..6696a5b8 100644 --- a/src/include/ipxe/console.h +++ b/src/include/ipxe/console.h @@ -28,6 +28,14 @@ struct console_configuration { unsigned int height; /** Colour depth */ unsigned int bpp; + /** Left margin */ + unsigned int left; + /** Right margin */ + unsigned int right; + /** Top margin */ + unsigned int top; + /** Bottom margin */ + unsigned int bottom; /** Background picture, if any */ struct pixel_buffer *pixbuf; }; diff --git a/src/include/ipxe/fbcon.h b/src/include/ipxe/fbcon.h index 007e7e72..0538449a 100644 --- a/src/include/ipxe/fbcon.h +++ b/src/include/ipxe/fbcon.h @@ -145,6 +145,7 @@ struct fbcon { extern int fbcon_init ( struct fbcon *fbcon, userptr_t start, struct fbcon_geometry *pixel, + struct fbcon_margin *margin, struct fbcon_colour_map *map, struct fbcon_font *font, struct pixel_buffer *pixbuf );