/** Font definition */
struct fbcon_font font;
/** Character glyphs */
- struct segoff glyphs;
+ const uint8_t *glyphs;
/** Saved VGA mode */
uint8_t saved_mode;
};
* Get character glyph
*
* @v character Unicode character
- * @v glyph Character glyph to fill in
+ * @ret glyph Character glyph
*/
-static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
+static const uint8_t * vesafb_glyph ( unsigned int character ) {
unsigned int index;
- size_t offset;
/* Identify glyph */
if ( character < VESAFB_ASCII ) {
index = VESAFB_UNKNOWN;
}
- /* Copy glyph from BIOS font table */
- offset = ( index * VESAFB_CHAR_HEIGHT );
- copy_from_real ( glyph, vesafb.glyphs.segment,
- ( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT);
+ /* Return glyph in BIOS font table */
+ return &vesafb.glyphs[ index * VESAFB_CHAR_HEIGHT ];
}
/**
*
*/
static void vesafb_font ( void ) {
+ struct segoff glyphs;
/* Get font information
*
"movw %%es, %%cx\n\t"
"movw %%bp, %%dx\n\t"
"popw %%bp\n\t" /* gcc bug */ )
- : "=c" ( vesafb.glyphs.segment ),
- "=d" ( vesafb.glyphs.offset )
+ : "=c" ( glyphs.segment ),
+ "=d" ( glyphs.offset )
: "a" ( VBE_GET_FONT ),
"b" ( VESAFB_FONT ) );
DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n",
- VESAFB_FONT, vesafb.glyphs.segment, vesafb.glyphs.offset );
+ VESAFB_FONT, glyphs.segment, glyphs.offset );
+ vesafb.glyphs = real_to_virt ( glyphs.segment, glyphs.offset );
vesafb.font.height = VESAFB_CHAR_HEIGHT;
vesafb.font.glyph = vesafb_glyph;
}
*/
static int vesafb_mode_list ( uint16_t **mode_numbers ) {
struct vbe_controller_info *controller = &vbe_buf.controller;
- userptr_t video_mode_ptr;
- uint16_t mode_number;
+ const uint16_t *video_mode_ptr;
+ const uint16_t *mode_number;
uint16_t status;
size_t len;
int rc;
/* Calculate length of mode list */
video_mode_ptr = real_to_virt ( controller->video_mode_ptr.segment,
controller->video_mode_ptr.offset );
- len = 0;
- do {
- copy_from_user ( &mode_number, video_mode_ptr, len,
- sizeof ( mode_number ) );
- len += sizeof ( mode_number );
- } while ( mode_number != VBE_MODE_END );
+ mode_number = video_mode_ptr;
+ while ( *(mode_number++) != VBE_MODE_END ) {}
+ len = ( ( ( const void * ) mode_number ) -
+ ( ( const void * ) video_mode_ptr ) );
/* Allocate and fill mode list */
*mode_numbers = malloc ( len );
if ( ! *mode_numbers )
return -ENOMEM;
- copy_from_user ( *mode_numbers, video_mode_ptr, 0, len );
+ memcpy ( *mode_numbers, video_mode_ptr, len );
return 0;
}
fbcon->background = FBCON_TRANSPARENT;
}
+/**
+ * Get character cell
+ *
+ * @v fbcon Frame buffer console
+ * @v xpos X position
+ * @v ypos Y position
+ * @ret cell Text cell
+ */
+static inline struct fbcon_text_cell * fbcon_cell ( struct fbcon *fbcon,
+ unsigned int xpos,
+ unsigned int ypos ) {
+ unsigned int index;
+
+ index = ( ( ypos * fbcon->character.width ) + xpos );
+ return &fbcon->text.cells[index];
+}
+
/**
* Clear rows of characters
*
* @v ypos Starting Y position
*/
static void fbcon_clear ( struct fbcon *fbcon, unsigned int ypos ) {
- struct fbcon_text_cell cell = {
- .foreground = fbcon->foreground,
- .background = fbcon->background,
- .character = ' ',
- };
- size_t offset;
+ struct fbcon_text_cell *cell;
unsigned int xpos;
/* Clear stored character array */
+ cell = fbcon_cell ( fbcon, 0, ypos );
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 );
+ cell->foreground = fbcon->foreground;
+ cell->background = fbcon->background;
+ cell->character = ' ';
+ cell++;
}
}
}
-/**
- * Store character at specified position
- *
- * @v fbcon Frame buffer console
- * @v cell Text cell
- * @v xpos X position
- * @v ypos Y position
- */
-static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
- unsigned int xpos, unsigned int ypos ) {
- size_t offset;
-
- /* Store cell */
- offset = ( ( ( ypos * fbcon->character.width ) + xpos ) *
- sizeof ( *cell ) );
- copy_to_user ( fbcon->text.start, offset, cell, sizeof ( *cell ) );
-}
-
/**
* Draw character at specified position
*
*/
static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
unsigned int xpos, unsigned int ypos ) {
- uint8_t glyph[fbcon->font->height];
+ const uint8_t *glyph;
size_t offset;
size_t pixel_len;
size_t skip_len;
unsigned int column;
uint8_t bitmask;
int transparent;
- void *src;
+ const void *src;
/* Get font character */
- fbcon->font->glyph ( cell->character, glyph );
+ glyph = fbcon->font->glyph ( cell->character );
/* Calculate pixel geometry */
offset = ( fbcon->indent +
} else {
continue;
}
- copy_to_user ( fbcon->start, offset, src, pixel_len );
+ memcpy ( ( fbcon->start + offset ), src, pixel_len );
}
/* Move to next row */
* @v fbcon Frame buffer console
*/
static void fbcon_redraw ( struct fbcon *fbcon ) {
- struct fbcon_text_cell cell;
- size_t offset = 0;
+ struct fbcon_text_cell *cell;
unsigned int xpos;
unsigned int ypos;
/* Redraw characters */
+ cell = fbcon_cell ( fbcon, 0, 0 );
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 );
+ fbcon_draw ( fbcon, cell, xpos, ypos );
+ cell++;
}
}
}
assert ( fbcon->ypos == fbcon->character.height );
/* Scroll up character array */
- row_len = ( fbcon->character.width * sizeof ( struct fbcon_text_cell ));
- memmove ( fbcon->text.start, ( fbcon->text.start + row_len ),
+ row_len = ( fbcon->character.width * sizeof ( fbcon->text.cells[0] ) );
+ memmove ( fbcon_cell ( fbcon, 0, 0 ), fbcon_cell ( fbcon, 0, 1 ),
( row_len * ( fbcon->character.height - 1 ) ) );
fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) );
* @v show_cursor Show cursor
*/
static void fbcon_draw_cursor ( struct fbcon *fbcon, int show_cursor ) {
- struct fbcon_text_cell cell;
- size_t offset;
+ struct fbcon_text_cell *cell;
+ struct fbcon_text_cell cursor;
- offset = ( ( ( fbcon->ypos * fbcon->character.width ) + fbcon->xpos ) *
- sizeof ( cell ) );
- copy_from_user ( &cell, fbcon->text.start, offset, sizeof ( cell ) );
+ cell = fbcon_cell ( fbcon, fbcon->xpos, fbcon->ypos );
if ( show_cursor ) {
- cell.background = fbcon->foreground;
- cell.foreground = ( ( fbcon->background == FBCON_TRANSPARENT ) ?
- 0 : fbcon->background );
+ cursor.background = fbcon->foreground;
+ cursor.foreground =
+ ( ( fbcon->background == FBCON_TRANSPARENT ) ?
+ 0 : fbcon->background );
+ cursor.character = cell->character;
+ cell = &cursor;
}
- fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
+ fbcon_draw ( fbcon, cell, fbcon->xpos, fbcon->ypos );
}
/**
* @v character Character
*/
void fbcon_putchar ( struct fbcon *fbcon, int character ) {
- struct fbcon_text_cell cell;
+ struct fbcon_text_cell *cell;
/* Intercept ANSI escape sequences */
character = ansiesc_process ( &fbcon->ctx, character );
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 );
+ cell = fbcon_cell ( fbcon, fbcon->xpos, fbcon->ypos );
+ cell->foreground = ( fbcon->foreground | fbcon->bold );
+ cell->background = fbcon->background;
+ cell->character = character;
+ fbcon_draw ( fbcon, cell, fbcon->xpos, fbcon->ypos );
/* Advance cursor */
fbcon->xpos++;
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;
+ const uint32_t *rgb;
uint32_t raw;
unsigned int x;
unsigned int y;
}
/* 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;
memset ( picture->start, 0, len );
for ( y = 0 ; y < height ; y++ ) {
offset = ( indent + ( y * pixel->stride ) );
- pixbuf_offset = ( pixbuf_indent + ( y * pixbuf_stride ) );
+ rgb = pixbuf_pixel ( pixbuf, ( ( xgap < 0 ) ? -xgap : 0 ),
+ ( ( ( ygap < 0 ) ? -ygap : 0 ) + y ) );
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 );
+ raw = fbcon_colour ( fbcon, *rgb );
+ memcpy ( ( picture->start + offset ), &raw,
+ pixel->len );
offset += pixel->len;
- pixbuf_offset += sizeof ( rgb );
+ rgb++;
}
}
* @v config Console configuration
* @ret rc Return status code
*/
-int fbcon_init ( struct fbcon *fbcon, userptr_t start,
+int fbcon_init ( struct fbcon *fbcon, void *start,
struct fbcon_geometry *pixel,
struct fbcon_colour_map *map,
struct fbcon_font *font,
fbcon_set_default_background ( fbcon );
/* Allocate and initialise stored character array */
- fbcon->text.start = umalloc ( fbcon->character.width *
+ fbcon->text.cells = umalloc ( fbcon->character.width *
fbcon->character.height *
- sizeof ( struct fbcon_text_cell ) );
- if ( ! fbcon->text.start ) {
+ sizeof ( fbcon->text.cells[0] ) );
+ if ( ! fbcon->text.cells ) {
rc = -ENOMEM;
goto err_text;
}
ufree ( fbcon->picture.start );
err_picture:
- ufree ( fbcon->text.start );
+ ufree ( fbcon->text.cells );
err_text:
err_margin:
return rc;
*/
void fbcon_fini ( struct fbcon *fbcon ) {
- ufree ( fbcon->text.start );
+ ufree ( fbcon->text.cells );
ufree ( fbcon->picture.start );
}