iPXE
fbcon.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Frame buffer console
29  *
30  */
31 
32 #include <string.h>
33 #include <errno.h>
34 #include <assert.h>
35 #include <byteswap.h>
36 #include <ipxe/ansiesc.h>
37 #include <ipxe/image.h>
38 #include <ipxe/pixbuf.h>
39 #include <ipxe/umalloc.h>
40 #include <ipxe/console.h>
41 #include <ipxe/fbcon.h>
42 
43 /**
44  * Calculate raw colour value
45  *
46  * @v fbcon Frame buffer console
47  * @v rgb 24-bit RGB value
48  * @ret raw Raw colour
49  */
50 static uint32_t fbcon_colour ( struct fbcon *fbcon, uint32_t rgb ) {
51  struct fbcon_colour_map *map = fbcon->map;
52  uint8_t red = ( rgb >> 16 );
53  uint8_t green = ( rgb >> 8 );
54  uint8_t blue = ( rgb >> 0 );
55  uint32_t mapped;
56 
57  mapped = ( ( ( red >> map->red_scale ) << map->red_lsb ) |
58  ( ( green >> map->green_scale ) << map->green_lsb ) |
59  ( ( blue >> map->blue_scale ) << map->blue_lsb ) );
60  return cpu_to_le32 ( mapped );
61 }
62 
63 /**
64  * Calculate ANSI font colour
65  *
66  * @v fbcon Frame buffer console
67  * @v ansicol ANSI colour value (0-based)
68  * @ret colour Raw colour
69  */
71  unsigned int ansicol ) {
72  uint32_t rgb;
73 
74  /* Treat ansicol as 3-bit BGR with intensity 0xaa */
75  rgb = ( ( ( ansicol & ( 1 << 0 ) ) ? 0xaa0000 : 0 ) |
76  ( ( ansicol & ( 1 << 1 ) ) ? 0x00aa00 : 0 ) |
77  ( ( ansicol & ( 1 << 2 ) ) ? 0x0000aa : 0 ) );
78 
79  return fbcon_colour ( fbcon, rgb );
80 }
81 
82 /**
83  * Set default foreground colour
84  *
85  * @v fbcon Frame buffer console
86  */
87 static void fbcon_set_default_foreground ( struct fbcon *fbcon ) {
88 
89  /* Default to non-bold white foreground */
91  fbcon->bold = 0;
92 }
93 
94 /**
95  * Set default background colour
96  *
97  * @v fbcon Frame buffer console
98  */
99 static void fbcon_set_default_background ( struct fbcon *fbcon ) {
100 
101  /* Default to transparent background */
103 }
104 
105 /**
106  * Clear rows of characters
107  *
108  * @v fbcon Frame buffer console
109  * @v ypos Starting Y position
110  */
111 static void fbcon_clear ( struct fbcon *fbcon, unsigned int ypos ) {
112  struct fbcon_text_cell cell = {
114  .background = fbcon->background,
115  .character = ' ',
116  };
117  size_t offset;
118  unsigned int xpos;
119 
120  /* Clear stored character array */
121  for ( ; ypos < fbcon->character.height ; ypos++ ) {
122  offset = ( ypos * fbcon->character.width * sizeof ( cell ) );
123  for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
124  copy_to_user ( fbcon->text.start, offset, &cell,
125  sizeof ( cell ) );
126  offset += sizeof ( cell );
127  }
128  }
129 }
130 
131 /**
132  * Store character at specified position
133  *
134  * @v fbcon Frame buffer console
135  * @v cell Text cell
136  * @v xpos X position
137  * @v ypos Y position
138  */
139 static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
140  unsigned int xpos, unsigned int ypos ) {
141  size_t offset;
142 
143  /* Store cell */
144  offset = ( ( ( ypos * fbcon->character.width ) + xpos ) *
145  sizeof ( *cell ) );
146  copy_to_user ( fbcon->text.start, offset, cell, sizeof ( *cell ) );
147 }
148 
149 /**
150  * Draw character at specified position
151  *
152  * @v fbcon Frame buffer console
153  * @v cell Text cell
154  * @v xpos X position
155  * @v ypos Y position
156  */
157 static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
158  unsigned int xpos, unsigned int ypos ) {
159  uint8_t glyph[fbcon->font->height];
160  size_t offset;
161  size_t pixel_len;
162  size_t skip_len;
163  unsigned int row;
164  unsigned int column;
165  uint8_t bitmask;
166  int transparent;
167  void *src;
168 
169  /* Get font character */
170  fbcon->font->glyph ( cell->character, glyph );
171 
172  /* Calculate pixel geometry */
173  offset = ( fbcon->indent +
174  ( ypos * fbcon->character.stride ) +
175  ( xpos * fbcon->character.len ) );
176  pixel_len = fbcon->pixel->len;
177  skip_len = ( fbcon->pixel->stride - fbcon->character.len );
178 
179  /* Check for transparent background colour */
180  transparent = ( cell->background == FBCON_TRANSPARENT );
181 
182  /* Draw character rows */
183  for ( row = 0 ; row < fbcon->font->height ; row++ ) {
184 
185  /* Draw background picture, if applicable */
186  if ( transparent ) {
187  if ( fbcon->picture.start ) {
190  fbcon->character.len );
191  } else {
192  memset_user ( fbcon->start, offset, 0,
193  fbcon->character.len );
194  }
195  }
196 
197  /* Draw character row */
198  for ( column = FBCON_CHAR_WIDTH, bitmask = glyph[row] ;
199  column ; column--, bitmask <<= 1, offset += pixel_len ) {
200  if ( bitmask & 0x80 ) {
201  src = &cell->foreground;
202  } else if ( ! transparent ) {
203  src = &cell->background;
204  } else {
205  continue;
206  }
207  copy_to_user ( fbcon->start, offset, src, pixel_len );
208  }
209 
210  /* Move to next row */
211  offset += skip_len;
212  }
213 }
214 
215 /**
216  * Redraw all characters
217  *
218  * @v fbcon Frame buffer console
219  */
220 static void fbcon_redraw ( struct fbcon *fbcon ) {
221  struct fbcon_text_cell cell;
222  size_t offset = 0;
223  unsigned int xpos;
224  unsigned int ypos;
225 
226  /* Redraw characters */
227  for ( ypos = 0 ; ypos < fbcon->character.height ; ypos++ ) {
228  for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
229  copy_from_user ( &cell, fbcon->text.start, offset,
230  sizeof ( cell ) );
231  fbcon_draw ( fbcon, &cell, xpos, ypos );
232  offset += sizeof ( cell );
233  }
234  }
235 }
236 
237 /**
238  * Scroll screen
239  *
240  * @v fbcon Frame buffer console
241  */
242 static void fbcon_scroll ( struct fbcon *fbcon ) {
243  size_t row_len;
244 
245  /* Sanity check */
247 
248  /* Scroll up character array */
249  row_len = ( fbcon->character.width * sizeof ( struct fbcon_text_cell ));
250  memmove_user ( fbcon->text.start, 0, fbcon->text.start, row_len,
251  ( row_len * ( fbcon->character.height - 1 ) ) );
252  fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) );
253 
254  /* Update cursor position */
255  fbcon->ypos--;
256 
257  /* Redraw all characters */
258  fbcon_redraw ( fbcon );
259 }
260 
261 /**
262  * Draw character at cursor position
263  *
264  * @v fbcon Frame buffer console
265  * @v show_cursor Show cursor
266  */
267 static void fbcon_draw_cursor ( struct fbcon *fbcon, int show_cursor ) {
268  struct fbcon_text_cell cell;
269  size_t offset;
270 
271  offset = ( ( ( fbcon->ypos * fbcon->character.width ) + fbcon->xpos ) *
272  sizeof ( cell ) );
273  copy_from_user ( &cell, fbcon->text.start, offset, sizeof ( cell ) );
274  if ( show_cursor ) {
275  cell.background = fbcon->foreground;
276  cell.foreground = ( ( fbcon->background == FBCON_TRANSPARENT ) ?
277  0 : fbcon->background );
278  }
279  fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
280 }
281 
282 /**
283  * Handle ANSI CUP (cursor position)
284  *
285  * @v ctx ANSI escape sequence context
286  * @v count Parameter count
287  * @v params[0] Row (1 is top)
288  * @v params[1] Column (1 is left)
289  */
290 static void fbcon_handle_cup ( struct ansiesc_context *ctx,
291  unsigned int count __unused, int params[] ) {
292  struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
293  int cx = ( params[1] - 1 );
294  int cy = ( params[0] - 1 );
295 
296  fbcon_draw_cursor ( fbcon, 0 );
297  fbcon->xpos = cx;
298  if ( fbcon->xpos >= fbcon->character.width )
299  fbcon->xpos = 0;
300  fbcon->ypos = cy;
301  if ( fbcon->ypos >= fbcon->character.height )
302  fbcon->ypos = 0;
304 }
305 
306 /**
307  * Handle ANSI ED (erase in page)
308  *
309  * @v ctx ANSI escape sequence context
310  * @v count Parameter count
311  * @v params[0] Region to erase
312  */
313 static void fbcon_handle_ed ( struct ansiesc_context *ctx,
314  unsigned int count __unused,
315  int params[] __unused ) {
316  struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
317 
318  /* We assume that we always clear the whole screen */
319  assert ( params[0] == ANSIESC_ED_ALL );
320 
321  /* Clear character array */
322  fbcon_clear ( fbcon, 0 );
323 
324  /* Redraw all characters */
325  fbcon_redraw ( fbcon );
326 
327  /* Reset cursor position */
328  fbcon->xpos = 0;
329  fbcon->ypos = 0;
331 }
332 
333 /**
334  * Handle ANSI SGR (set graphics rendition)
335  *
336  * @v ctx ANSI escape sequence context
337  * @v count Parameter count
338  * @v params List of graphic rendition aspects
339  */
340 static void fbcon_handle_sgr ( struct ansiesc_context *ctx, unsigned int count,
341  int params[] ) {
342  struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
343  uint32_t *custom = NULL;
344  uint32_t rgb;
345  unsigned int end;
346  unsigned int i;
347  int aspect;
348 
349  for ( i = 0 ; i < count ; i++ ) {
350 
351  /* Process aspect */
352  aspect = params[i];
353  if ( aspect == 0 ) {
356  } else if ( aspect == 1 ) {
358  } else if ( aspect == 22 ) {
359  fbcon->bold = 0;
360  } else if ( ( aspect >= 30 ) && ( aspect <= 37 ) ) {
361  fbcon->foreground =
362  fbcon_ansi_colour ( fbcon, aspect - 30 );
363  } else if ( aspect == 38 ) {
364  custom = &fbcon->foreground;
365  } else if ( aspect == 39 ) {
367  } else if ( ( aspect >= 40 ) && ( aspect <= 47 ) ) {
368  fbcon->background =
369  fbcon_ansi_colour ( fbcon, aspect - 40 );
370  } else if ( aspect == 48 ) {
371  custom = &fbcon->background;
372  } else if ( aspect == 49 ) {
374  }
375 
376  /* Process custom RGB colour, if applicable
377  *
378  * We support the xterm-compatible
379  * "<ESC>[38;2;<red>;<green>;<blue>m" and
380  * "<ESC>[48;2;<red>;<green>;<blue>m" sequences.
381  */
382  if ( custom ) {
383  rgb = 0;
384  end = ( i + 5 );
385  for ( ; ( i < count ) && ( i < end ) ; i++ )
386  rgb = ( ( rgb << 8 ) | params[i] );
387  *custom = fbcon_colour ( fbcon, rgb );
388  custom = NULL;
389  }
390  }
391 }
392 
393 /**
394  * Handle ANSI DECTCEM set (show cursor)
395  *
396  * @v ctx ANSI escape sequence context
397  * @v count Parameter count
398  * @v params List of graphic rendition aspects
399  */
401  unsigned int count __unused,
402  int params[] __unused ) {
403  struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
404 
405  fbcon->show_cursor = 1;
406  fbcon_draw_cursor ( fbcon, 1 );
407 }
408 
409 /**
410  * Handle ANSI DECTCEM reset (hide cursor)
411  *
412  * @v ctx ANSI escape sequence context
413  * @v count Parameter count
414  * @v params List of graphic rendition aspects
415  */
417  unsigned int count __unused,
418  int params[] __unused ) {
419  struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
420 
421  fbcon->show_cursor = 0;
422  fbcon_draw_cursor ( fbcon, 0 );
423 }
424 
425 /** ANSI escape sequence handlers */
432  { 0, NULL }
433 };
434 
435 /**
436  * Print a character to current cursor position
437  *
438  * @v fbcon Frame buffer console
439  * @v character Character
440  */
441 void fbcon_putchar ( struct fbcon *fbcon, int character ) {
442  struct fbcon_text_cell cell;
443 
444  /* Intercept ANSI escape sequences */
446  if ( character < 0 )
447  return;
448 
449  /* Accumulate Unicode characters */
451  if ( character == 0 )
452  return;
453 
454  /* Handle control characters */
455  switch ( character ) {
456  case '\r':
457  fbcon_draw_cursor ( fbcon, 0 );
458  fbcon->xpos = 0;
459  break;
460  case '\n':
461  fbcon_draw_cursor ( fbcon, 0 );
462  fbcon->xpos = 0;
463  fbcon->ypos++;
464  break;
465  case '\b':
466  fbcon_draw_cursor ( fbcon, 0 );
467  if ( fbcon->xpos ) {
468  fbcon->xpos--;
469  } else if ( fbcon->ypos ) {
470  fbcon->xpos = ( fbcon->character.width - 1 );
471  fbcon->ypos--;
472  }
473  break;
474  default:
475  /* Print character at current cursor position */
476  cell.foreground = ( fbcon->foreground | fbcon->bold );
477  cell.background = fbcon->background;
478  cell.character = character;
479  fbcon_store ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
480  fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
481 
482  /* Advance cursor */
483  fbcon->xpos++;
484  if ( fbcon->xpos >= fbcon->character.width ) {
485  fbcon->xpos = 0;
486  fbcon->ypos++;
487  }
488  break;
489  }
490 
491  /* Scroll screen if necessary */
492  if ( fbcon->ypos >= fbcon->character.height )
493  fbcon_scroll ( fbcon );
494 
495  /* Show cursor */
497 }
498 
499 /**
500  * Initialise background picture
501  *
502  * @v fbcon Frame buffer console
503  * @v pixbuf Background picture
504  * @ret rc Return status code
505  */
506 static int fbcon_picture_init ( struct fbcon *fbcon,
507  struct pixel_buffer *pixbuf ) {
508  struct fbcon_geometry *pixel = fbcon->pixel;
509  struct fbcon_picture *picture = &fbcon->picture;
510  size_t len;
511  size_t pixbuf_stride;
512  size_t indent;
513  size_t pixbuf_indent;
514  size_t offset;
515  size_t pixbuf_offset;
516  uint32_t rgb;
517  uint32_t raw;
518  unsigned int x;
519  unsigned int y;
520  unsigned int width;
521  unsigned int height;
522  int xgap;
523  int ygap;
524  int rc;
525 
526  /* Allocate buffer */
527  len = ( pixel->height * pixel->stride );
528  picture->start = umalloc ( len );
529  if ( ! picture->start ) {
530  DBGC ( fbcon, "FBCON %p could not allocate %zd bytes for "
531  "picture\n", fbcon, len );
532  rc = -ENOMEM;
533  goto err_umalloc;
534  }
535 
536  /* Centre picture on console */
537  pixbuf_stride = ( pixbuf->width * sizeof ( rgb ) );
538  xgap = ( ( ( int ) ( pixel->width - pixbuf->width ) ) / 2 );
539  ygap = ( ( ( int ) ( pixel->height - pixbuf->height ) ) / 2 );
540  indent = ( ( ( ( ygap >= 0 ) ? ygap : 0 ) * pixel->stride ) +
541  ( ( ( xgap >= 0 ) ? xgap : 0 ) * pixel->len ) );
542  pixbuf_indent = ( ( ( ( ygap < 0 ) ? -ygap : 0 ) * pixbuf_stride ) +
543  ( ( ( xgap < 0 ) ? -xgap : 0 ) * sizeof ( rgb ) ) );
544  width = pixbuf->width;
545  if ( width > pixel->width )
546  width = pixel->width;
547  height = pixbuf->height;
548  if ( height > pixel->height )
549  height = pixel->height;
550  DBGC ( fbcon, "FBCON %p picture is pixel %dx%d at [%d,%d),[%d,%d)\n",
551  fbcon, width, height, xgap, ( xgap + pixbuf->width ), ygap,
552  ( ygap + pixbuf->height ) );
553 
554  /* Convert to frame buffer raw format */
555  memset_user ( picture->start, 0, 0, len );
556  for ( y = 0 ; y < height ; y++ ) {
557  offset = ( indent + ( y * pixel->stride ) );
558  pixbuf_offset = ( pixbuf_indent + ( y * pixbuf_stride ) );
559  for ( x = 0 ; x < width ; x++ ) {
560  copy_from_user ( &rgb, pixbuf->data, pixbuf_offset,
561  sizeof ( rgb ) );
562  raw = fbcon_colour ( fbcon, rgb );
563  copy_to_user ( picture->start, offset, &raw,
564  pixel->len );
565  offset += pixel->len;
566  pixbuf_offset += sizeof ( rgb );
567  }
568  }
569 
570  return 0;
571 
572  ufree ( picture->start );
573  err_umalloc:
574  return rc;
575 }
576 
577 /**
578  * Initialise frame buffer console
579  *
580  * @v fbcon Frame buffer console
581  * @v start Start address
582  * @v pixel Pixel geometry
583  * @v map Colour mapping
584  * @v font Font definition
585  * @v config Console configuration
586  * @ret rc Return status code
587  */
589  struct fbcon_geometry *pixel,
590  struct fbcon_colour_map *map,
591  struct fbcon_font *font,
592  struct console_configuration *config ) {
593  int width;
594  int height;
595  unsigned int xgap;
596  unsigned int ygap;
597  unsigned int left;
598  unsigned int right;
599  unsigned int top;
600  unsigned int bottom;
601  int rc;
602 
603  /* Initialise data structure */
604  memset ( fbcon, 0, sizeof ( *fbcon ) );
605  fbcon->start = start;
606  fbcon->pixel = pixel;
607  assert ( pixel->len <= sizeof ( uint32_t ) );
608  fbcon->map = map;
609  fbcon->font = font;
611  fbcon->show_cursor = 1;
612 
613  /* Derive overall length */
614  fbcon->len = ( pixel->height * pixel->stride );
615  DBGC ( fbcon, "FBCON %p at [%08lx,%08lx)\n", fbcon,
616  user_to_phys ( fbcon->start, 0 ),
617  user_to_phys ( fbcon->start, fbcon->len ) );
618 
619  /* Calculate margin. If the actual screen size is larger than
620  * the requested screen size, then update the margins so that
621  * the margin remains relative to the requested screen size.
622  * (As an exception, if a zero margin was specified then treat
623  * this as meaning "expand to edge of actual screen".)
624  */
625  xgap = ( pixel->width - config->width );
626  ygap = ( pixel->height - config->height );
627  left = ( xgap / 2 );
628  right = ( xgap - left );
629  top = ( ygap / 2 );
630  bottom = ( ygap - top );
631  fbcon->margin.left = ( config->left + ( config->left ? left : 0 ) );
632  fbcon->margin.right = ( config->right + ( config->right ? right : 0 ) );
633  fbcon->margin.top = ( config->top + ( config->top ? top : 0 ) );
634  fbcon->margin.bottom =
635  ( config->bottom + ( config->bottom ? bottom : 0 ) );
636 
637  /* Expand margin to accommodate whole characters */
638  width = ( pixel->width - fbcon->margin.left - fbcon->margin.right );
639  height = ( pixel->height - fbcon->margin.top - fbcon->margin.bottom );
640  if ( ( width < FBCON_CHAR_WIDTH ) ||
641  ( height < ( ( int ) font->height ) ) ) {
642  DBGC ( fbcon, "FBCON %p has unusable character area "
643  "[%d-%d),[%d-%d)\n", fbcon, fbcon->margin.left,
644  ( pixel->width - fbcon->margin.right ),
645  fbcon->margin.top,
646  ( pixel->height - fbcon->margin.bottom ) );
647  rc = -EINVAL;
648  goto err_margin;
649  }
650  xgap = ( width % FBCON_CHAR_WIDTH );
651  ygap = ( height % font->height );
652  fbcon->margin.left += ( xgap / 2 );
653  fbcon->margin.top += ( ygap / 2 );
654  fbcon->margin.right += ( xgap - ( xgap / 2 ) );
655  fbcon->margin.bottom += ( ygap - ( ygap / 2 ) );
656  fbcon->indent = ( ( fbcon->margin.top * pixel->stride ) +
657  ( fbcon->margin.left * pixel->len ) );
658 
659  /* Derive character geometry from pixel geometry */
660  fbcon->character.width = ( width / FBCON_CHAR_WIDTH );
661  fbcon->character.height = ( height / font->height );
662  fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH );
663  fbcon->character.stride = ( pixel->stride * font->height );
664  DBGC ( fbcon, "FBCON %p is pixel %dx%d, char %dx%d at "
665  "[%d-%d),[%d-%d)\n", fbcon, fbcon->pixel->width,
668  ( fbcon->pixel->width - fbcon->margin.right ),
669  fbcon->margin.top,
670  ( fbcon->pixel->height - fbcon->margin.bottom ) );
671 
672  /* Set default colours */
675 
676  /* Allocate and initialise stored character array */
679  sizeof ( struct fbcon_text_cell ) );
680  if ( ! fbcon->text.start ) {
681  rc = -ENOMEM;
682  goto err_text;
683  }
684  fbcon_clear ( fbcon, 0 );
685 
686  /* Set framebuffer to all black (including margins) */
687  memset_user ( fbcon->start, 0, 0, fbcon->len );
688 
689  /* Generate pixel buffer from background image, if applicable */
690  if ( config->pixbuf &&
691  ( ( rc = fbcon_picture_init ( fbcon, config->pixbuf ) ) != 0 ) )
692  goto err_picture;
693 
694  /* Draw background picture (including margins), if applicable */
695  if ( fbcon->picture.start ) {
697  fbcon->len );
698  }
699 
700  /* Update console width and height */
702 
703  return 0;
704 
705  ufree ( fbcon->picture.start );
706  err_picture:
707  ufree ( fbcon->text.start );
708  err_text:
709  err_margin:
710  return rc;
711 }
712 
713 /**
714  * Finalise frame buffer console
715  *
716  * @v fbcon Frame buffer console
717  */
718 void fbcon_fini ( struct fbcon *fbcon ) {
719 
720  ufree ( fbcon->text.start );
721  ufree ( fbcon->picture.start );
722 }
static void console_set_size(unsigned int width, unsigned int height)
Set console size.
Definition: console.h:201
unsigned int height
Character height (in pixels)
Definition: fbcon.h:36
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct ansiesc_handler fbcon_ansiesc_handlers[]
ANSI escape sequence handlers.
Definition: fbcon.c:426
A frame buffer geometry.
Definition: fbcon.h:51
static void fbcon_draw(struct fbcon *fbcon, struct fbcon_text_cell *cell, unsigned int xpos, unsigned int ypos)
Draw character at specified position.
Definition: fbcon.c:157
A handler for an escape sequence.
Definition: ansiesc.h:34
#define FBCON_BOLD
Bold colour modifier (RGB value)
Definition: fbcon.h:22
struct ansiesc_handler * handlers
Array of handlers.
Definition: ansiesc.h:79
unsigned int height
Height.
Definition: console.h:28
userptr_t start
Start address.
Definition: fbcon.h:109
unsigned int ypos
Text cursor Y position.
Definition: fbcon.h:139
Frame buffer console.
Error codes.
static uint32_t fbcon_ansi_colour(struct fbcon *fbcon, unsigned int ansicol)
Calculate ANSI font colour.
Definition: fbcon.c:70
unsigned int height
Height.
Definition: pixbuf.h:23
unsigned int bottom
Bottom margin.
Definition: fbcon.h:71
struct fbcon_font * font
Font definition.
Definition: fbcon.h:129
unsigned int width
Width (number of entities per displayed row)
Definition: fbcon.h:53
static void fbcon_draw_cursor(struct fbcon *fbcon, int show_cursor)
Draw character at cursor position.
Definition: fbcon.c:267
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
struct fbcon_geometry character
Character geometry.
Definition: fbcon.h:121
unsigned long user_to_phys(userptr_t userptr, off_t offset)
Convert user pointer to physical address.
#define DBGC(...)
Definition: compiler.h:505
struct ansiesc_context ctx
ANSI escape sequence context.
Definition: fbcon.h:141
static void fbcon_handle_dectcem_reset(struct ansiesc_context *ctx, unsigned int count __unused, int params[] __unused)
Handle ANSI DECTCEM reset (hide cursor)
Definition: fbcon.c:416
void fbcon_putchar(struct fbcon *fbcon, int character)
Print a character to current cursor position.
Definition: fbcon.c:441
A frame buffer text cell.
Definition: fbcon.h:91
static uint32_t fbcon_colour(struct fbcon *fbcon, uint32_t rgb)
Calculate raw colour value.
Definition: fbcon.c:50
unsigned int width
Width.
Definition: console.h:26
static userptr_t bottom
Bottom of heap (current lowest allocated block)
ANSI escape sequence context.
Definition: ansiesc.h:73
Pixel buffer.
void(* glyph)(unsigned int character, uint8_t *glyph)
Get character glyph.
Definition: fbcon.h:43
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void fbcon_handle_cup(struct ansiesc_context *ctx, unsigned int count __unused, int params[])
Handle ANSI CUP (cursor position)
Definition: fbcon.c:290
static void fbcon_clear(struct fbcon *fbcon, unsigned int ypos)
Clear rows of characters.
Definition: fbcon.c:111
A console configuration.
Definition: console.h:24
uint16_t cx
Definition: registers.h:51
struct fbcon_geometry * pixel
Pixel geometry.
Definition: fbcon.h:119
unsigned int left
Left margin.
Definition: fbcon.h:65
#define ANSIESC_ED
Erase in page.
Definition: ansiesc.h:106
uint32_t start
Starting offset.
Definition: netvsc.h:12
int ansiesc_process(struct ansiesc_context *ctx, int c)
Process character that may be part of ANSI escape sequence.
Definition: ansiesc.c:74
unsigned int bottom
Bottom margin.
Definition: console.h:38
static void fbcon_scroll(struct fbcon *fbcon)
Scroll screen.
Definition: fbcon.c:242
#define ANSIESC_ED_ALL
Erase whole page.
Definition: ansiesc.h:115
void memset_user(userptr_t userptr, off_t offset, int c, size_t len)
Fill user buffer with a constant byte.
#define ENOMEM
Not enough space.
Definition: errno.h:534
uint32_t background
Background colour.
Definition: fbcon.h:95
#define ANSIESC_CUP
Cursor position.
Definition: ansiesc.h:103
A frame buffer background picture.
Definition: fbcon.h:107
uint32_t foreground
Text foreground raw colour.
Definition: fbcon.h:131
size_t len
Length of a single entity.
Definition: fbcon.h:57
Assertions.
A frame buffer console.
Definition: fbcon.h:113
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void fbcon_handle_ed(struct ansiesc_context *ctx, unsigned int count __unused, int params[] __unused)
Handle ANSI ED (erase in page)
Definition: fbcon.c:313
Executable images.
ANSI escape sequences.
A frame buffer colour mapping.
Definition: fbcon.h:75
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static void fbcon_set_default_background(struct fbcon *fbcon)
Set default background colour.
Definition: fbcon.c:99
static void fbcon_handle_sgr(struct ansiesc_context *ctx, unsigned int count, int params[])
Handle ANSI SGR (set graphics rendition)
Definition: fbcon.c:340
#define ANSIESC_SGR
Select graphic rendition.
Definition: ansiesc.h:118
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.
Definition: fbcon.c:588
unsigned int top
Top margin.
Definition: fbcon.h:69
static void fbcon_handle_dectcem_set(struct ansiesc_context *ctx, unsigned int count __unused, int params[] __unused)
Handle ANSI DECTCEM set (show cursor)
Definition: fbcon.c:400
User interaction.
#define cpu_to_le32(value)
Definition: byteswap.h:107
unsigned int character
Unicode character.
Definition: fbcon.h:97
userptr_t start
Stored text cells.
Definition: fbcon.h:103
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
void fbcon_fini(struct fbcon *fbcon)
Finalise frame buffer console.
Definition: fbcon.c:718
uint32_t foreground
Foreground colour.
Definition: fbcon.h:93
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static userptr_t top
Top of heap.
A pixel buffer.
Definition: pixbuf.h:17
static __always_inline void copy_to_user(userptr_t dest, off_t dest_off, const void *src, size_t len)
Copy data to user buffer.
Definition: uaccess.h:324
User memory allocation.
uint32_t column[4]
Viewed as an array of four-byte columns.
Definition: aes.h:14
unsigned char uint8_t
Definition: stdint.h:10
unsigned int xpos
Text cursor X position.
Definition: fbcon.h:137
struct fbcon_margin margin
Margin.
Definition: fbcon.h:123
static __always_inline int struct dma_mapping * map
Definition: dma.h:181
unsigned int right
Right margin.
Definition: console.h:34
unsigned int uint32_t
Definition: stdint.h:12
#define FBCON_CHAR_WIDTH
Character width, in pixels.
Definition: fbcon.h:19
A font definition.
Definition: fbcon.h:34
static int fbcon_picture_init(struct fbcon *fbcon, struct pixel_buffer *pixbuf)
Initialise background picture.
Definition: fbcon.c:506
uint32_t background
Text background raw colour.
Definition: fbcon.h:133
#define FBCON_TRANSPARENT
Transparent background magic colour (raw colour value)
Definition: fbcon.h:25
#define ANSIESC_DECTCEM_RESET
Hide cursor.
Definition: ansiesc.h:131
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
struct fbcon_text text
Text array.
Definition: fbcon.h:145
struct utf8_accumulator utf8
UTF-8 accumulator.
Definition: fbcon.h:143
#define ANSIESC_DECTCEM_SET
Show cursor.
Definition: ansiesc.h:128
size_t len
Length of one complete displayed screen.
Definition: fbcon.h:117
static __always_inline void ufree(userptr_t userptr)
Free external memory.
Definition: umalloc.h:65
uint32_t len
Length.
Definition: ena.h:14
static __always_inline userptr_t umalloc(size_t size)
Allocate external memory.
Definition: umalloc.h:54
unsigned int height
Height (number of entities per displayed column)
Definition: fbcon.h:55
struct pixel_buffer * pixbuf
Background picture, if any.
Definition: console.h:40
unsigned int top
Top margin.
Definition: console.h:36
unsigned int right
Right margin.
Definition: fbcon.h:67
uint16_t count
Number of entries.
Definition: ena.h:22
uint32_t end
Ending offset.
Definition: netvsc.h:18
unsigned int utf8_accumulate(struct utf8_accumulator *utf8, uint8_t byte)
Accumulate Unicode character from UTF-8 byte sequence.
Definition: utf8.c:43
uint32_t bold
Bold colour modifier raw colour.
Definition: fbcon.h:135
__be32 raw[7]
Definition: CIB_PRM.h:28
struct fbcon_picture picture
Background picture.
Definition: fbcon.h:147
void memmove_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers, allowing for overlap.
size_t indent
Indent to first character (in bytes)
Definition: fbcon.h:125
userptr_t data
32-bit (8:8:8:8) xRGB pixel data, in host-endian order
Definition: pixbuf.h:25
struct fbcon_colour_map * map
Colour mapping.
Definition: fbcon.h:127
userptr_t start
Start address.
Definition: fbcon.h:115
static void fbcon_store(struct fbcon *fbcon, struct fbcon_text_cell *cell, unsigned int xpos, unsigned int ypos)
Store character at specified position.
Definition: fbcon.c:139
int show_cursor
Display cursor.
Definition: fbcon.h:149
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static void fbcon_set_default_foreground(struct fbcon *fbcon)
Set default foreground colour.
Definition: fbcon.c:87
String functions.
size_t stride
Stride (offset between vertically adjacent entities)
Definition: fbcon.h:59
static void fbcon_redraw(struct fbcon *fbcon)
Redraw all characters.
Definition: fbcon.c:220
void memcpy_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers.
unsigned int width
Width.
Definition: pixbuf.h:21
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
unsigned int left
Left margin.
Definition: console.h:32
void * memset(void *dest, int character, size_t len) __nonnull