2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/machine/memory.h>
20 #include <grub/machine/console.h>
21 #include <grub/term.h>
22 #include <grub/types.h>
24 #include <grub/misc.h>
25 #include <grub/normal.h>
26 #include <grub/font.h>
30 #include <grub/video.h>
31 #include <grub/bitmap.h>
33 #define DEFAULT_VIDEO_WIDTH 640
34 #define DEFAULT_VIDEO_HEIGHT 480
35 #define DEFAULT_VIDEO_FLAGS 0
37 #define DEFAULT_CHAR_WIDTH 8
38 #define DEFAULT_CHAR_HEIGHT 16
40 #define DEFAULT_BORDER_WIDTH 10
42 #define DEFAULT_STANDARD_COLOR 0x07
43 #define DEFAULT_NORMAL_COLOR 0x07
44 #define DEFAULT_HIGHLIGHT_COLOR 0x70
45 #define DEFAULT_CURSOR_COLOR 0x07
47 struct grub_dirty_region
55 struct grub_colored_char
57 /* An Unicode codepoint. */
61 grub_video_color_t fg_color
;
62 grub_video_color_t bg_color
;
64 /* The width of this character minus one. */
67 /* The column index of this character. */
71 struct grub_virtual_screen
73 /* Dimensions of the virtual screen. */
77 /* Offset in the display. */
78 unsigned int offset_x
;
79 unsigned int offset_y
;
81 /* TTY Character sizes. */
82 unsigned int char_width
;
83 unsigned int char_height
;
85 /* Virtual screen TTY size. */
89 /* Current cursor details. */
90 unsigned int cursor_x
;
91 unsigned int cursor_y
;
94 /* Terminal color settings. */
95 grub_uint8_t standard_color_setting
;
96 grub_uint8_t normal_color_setting
;
97 grub_uint8_t highlight_color_setting
;
98 grub_uint8_t term_color
;
100 /* Color settings. */
101 grub_video_color_t fg_color
;
102 grub_video_color_t bg_color
;
103 grub_video_color_t cursor_color
;
105 /* Text buffer for virtual screen. Contains (columns * rows) number
107 struct grub_colored_char
*text_buffer
;
110 static struct grub_virtual_screen virtual_screen
;
112 static grub_dl_t my_mod
;
113 static struct grub_video_mode_info mode_info
;
115 static struct grub_video_render_target
*text_layer
;
117 static unsigned int bitmap_width
;
118 static unsigned int bitmap_height
;
119 static struct grub_video_bitmap
*bitmap
;
121 static struct grub_dirty_region dirty_region
;
123 static void dirty_region_reset (void);
125 static int dirty_region_is_empty (void);
127 static void dirty_region_add (int x
, int y
,
128 unsigned int width
, unsigned int height
);
131 set_term_color (grub_uint8_t term_color
)
133 struct grub_video_render_target
*old_target
;
135 /* Save previous target and switch to text layer. */
136 grub_video_get_active_render_target (&old_target
);
137 grub_video_set_active_render_target (text_layer
);
139 /* Map terminal color to text layer compatible video colors. */
140 virtual_screen
.fg_color
= grub_video_map_color(term_color
& 0x0f);
142 /* Special case: use black as transparent color. */
143 if (((term_color
>> 4) & 0x0f) == 0)
145 virtual_screen
.bg_color
= grub_video_map_rgba(0, 0, 0, 0);
149 virtual_screen
.bg_color
= grub_video_map_color((term_color
>> 4) & 0x0f);
152 /* Restore previous target. */
153 grub_video_set_active_render_target (old_target
);
157 grub_virtual_screen_free (void)
159 /* If virtual screen has been allocated, free it. */
160 if (virtual_screen
.text_buffer
!= 0)
161 grub_free (virtual_screen
.text_buffer
);
163 /* Reset virtual screen data. */
164 grub_memset (&virtual_screen
, 0, sizeof (virtual_screen
));
166 /* Free render targets. */
167 grub_video_delete_render_target (text_layer
);
172 grub_virtual_screen_setup (unsigned int x
, unsigned int y
,
173 unsigned int width
, unsigned int height
)
175 /* Free old virtual screen. */
176 grub_virtual_screen_free ();
178 /* Initialize with default data. */
179 virtual_screen
.width
= width
;
180 virtual_screen
.height
= height
;
181 virtual_screen
.offset_x
= x
;
182 virtual_screen
.offset_y
= y
;
183 virtual_screen
.char_width
= DEFAULT_CHAR_WIDTH
;
184 virtual_screen
.char_height
= DEFAULT_CHAR_HEIGHT
;
185 virtual_screen
.cursor_x
= 0;
186 virtual_screen
.cursor_y
= 0;
187 virtual_screen
.cursor_state
= 1;
189 /* Calculate size of text buffer. */
190 virtual_screen
.columns
= virtual_screen
.width
/ virtual_screen
.char_width
;
191 virtual_screen
.rows
= virtual_screen
.height
/ virtual_screen
.char_height
;
193 /* Allocate memory for text buffer. */
194 virtual_screen
.text_buffer
=
195 (struct grub_colored_char
*) grub_malloc (virtual_screen
.columns
196 * virtual_screen
.rows
197 * sizeof (*virtual_screen
.text_buffer
));
198 if (grub_errno
!= GRUB_ERR_NONE
)
201 /* Create new render target for text layer. */
202 grub_video_create_render_target (&text_layer
,
203 virtual_screen
.width
,
204 virtual_screen
.height
,
205 GRUB_VIDEO_MODE_TYPE_RGB
206 | GRUB_VIDEO_MODE_TYPE_ALPHA
);
207 if (grub_errno
!= GRUB_ERR_NONE
)
210 /* As we want to have colors compatible with rendering target,
211 we can only have those after mode is initialized. */
212 grub_video_set_active_render_target (text_layer
);
214 virtual_screen
.standard_color_setting
= DEFAULT_STANDARD_COLOR
;
215 virtual_screen
.normal_color_setting
= DEFAULT_NORMAL_COLOR
;
216 virtual_screen
.highlight_color_setting
= DEFAULT_HIGHLIGHT_COLOR
;
218 virtual_screen
.term_color
= virtual_screen
.normal_color_setting
;
220 set_term_color (virtual_screen
.term_color
);
222 virtual_screen
.cursor_color
= grub_video_map_color (DEFAULT_CURSOR_COLOR
);
224 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
230 grub_gfxterm_init (void)
233 int width
= DEFAULT_VIDEO_WIDTH
;
234 int height
= DEFAULT_VIDEO_HEIGHT
;
236 int flags
= DEFAULT_VIDEO_FLAGS
;
237 grub_video_color_t color
;
239 /* Parse gfxmode environment variable if set. */
240 modevar
= grub_env_get ("gfxmode");
250 /* Take copy of env.var. as we don't want to modify that. */
251 tmp
= grub_strdup (modevar
);
254 if (grub_errno
!= GRUB_ERR_NONE
)
257 /* Initialize next mode. */
260 /* Loop until all modes has been tested out. */
261 while (next_mode
!= NULL
)
263 /* Use last next_mode as current mode. */
266 /* Reset video mode settings. */
267 width
= DEFAULT_VIDEO_WIDTH
;
268 height
= DEFAULT_VIDEO_HEIGHT
;
270 flags
= DEFAULT_VIDEO_FLAGS
;
272 /* Save position of next mode and separate modes. */
273 next_mode
= grub_strchr(next_mode
, ';');
280 /* Skip whitespace. */
281 while (grub_isspace (*tmp
))
284 /* Initialize token holders. */
289 /* Parse <width>x<height>[x<depth>]*/
291 /* Find width value. */
293 param
= grub_strchr(param
, 'x');
298 /* First setup error message. */
299 rc
= grub_error (GRUB_ERR_BAD_ARGUMENT
,
300 "Invalid mode: %s\n",
303 /* Free memory before returning. */
312 width
= grub_strtoul (value
, 0, 0);
313 if (grub_errno
!= GRUB_ERR_NONE
)
317 /* First setup error message. */
318 rc
= grub_error (GRUB_ERR_BAD_ARGUMENT
,
319 "Invalid mode: %s\n",
322 /* Free memory before returning. */
328 /* Find height value. */
330 param
= grub_strchr(param
, 'x');
333 height
= grub_strtoul (value
, 0, 0);
334 if (grub_errno
!= GRUB_ERR_NONE
)
338 /* First setup error message. */
339 rc
= grub_error (GRUB_ERR_BAD_ARGUMENT
,
340 "Invalid mode: %s\n",
343 /* Free memory before returning. */
351 /* We have optional color depth value. */
355 height
= grub_strtoul (value
, 0, 0);
356 if (grub_errno
!= GRUB_ERR_NONE
)
360 /* First setup error message. */
361 rc
= grub_error (GRUB_ERR_BAD_ARGUMENT
,
362 "Invalid mode: %s\n",
365 /* Free memory before returning. */
371 /* Convert color depth value. */
373 depth
= grub_strtoul (value
, 0, 0);
374 if (grub_errno
!= GRUB_ERR_NONE
)
378 /* First setup error message. */
379 rc
= grub_error (GRUB_ERR_BAD_ARGUMENT
,
380 "Invalid mode: %s\n",
383 /* Free memory before returning. */
390 /* Try out video mode. */
392 /* If we have 8 or less bits, then assume that it is indexed color mode. */
393 if ((depth
<= 8) && (depth
!= -1))
394 flags
|= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
;
396 /* We have more than 8 bits, then assume that it is RGB color mode. */
398 flags
|= GRUB_VIDEO_MODE_TYPE_RGB
;
400 /* If user requested specific depth, forward that information to driver. */
402 flags
|= (depth
<< GRUB_VIDEO_MODE_TYPE_DEPTH_POS
)
403 & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK
;
405 /* Try to initialize requested mode. Ignore any errors. */
407 if (grub_video_setup (width
, height
, flags
) != GRUB_ERR_NONE
)
413 /* Figure out what mode we ended up. */
414 if (grub_video_get_info (&mode_info
) != GRUB_ERR_NONE
)
416 /* Couldn't get video mode info, restore old mode and continue to next one. */
419 grub_video_restore ();
423 /* Restore state of error stack. */
426 /* Mode found! Exit loop. */
435 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
436 "No suitable mode found.");
440 /* No gfxmode variable set, use defaults. */
442 /* If we have 8 or less bits, then assume that it is indexed color mode. */
443 if ((depth
<= 8) && (depth
!= -1))
444 flags
|= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
;
446 /* We have more than 8 bits, then assume that it is RGB color mode. */
448 flags
|= GRUB_VIDEO_MODE_TYPE_RGB
;
450 /* If user requested specific depth, forward that information to driver. */
452 flags
|= (depth
<< GRUB_VIDEO_MODE_TYPE_DEPTH_POS
)
453 & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK
;
455 /* Initialize user requested mode. */
456 if (grub_video_setup (width
, height
, flags
) != GRUB_ERR_NONE
)
459 /* Figure out what mode we ended up. */
460 if (grub_video_get_info (&mode_info
) != GRUB_ERR_NONE
)
462 grub_video_restore ();
467 /* Make sure screen is black. */
468 color
= grub_video_map_rgb (0, 0, 0);
469 grub_video_fill_rect (color
, 0, 0, mode_info
.width
, mode_info
.height
);
472 /* Leave borders for virtual screen. */
473 width
= mode_info
.width
- (2 * DEFAULT_BORDER_WIDTH
);
474 height
= mode_info
.height
- (2 * DEFAULT_BORDER_WIDTH
);
476 /* Create virtual screen. */
477 if (grub_virtual_screen_setup (DEFAULT_BORDER_WIDTH
, DEFAULT_BORDER_WIDTH
,
478 width
, height
) != GRUB_ERR_NONE
)
480 grub_video_restore ();
484 /* Mark whole screen as dirty. */
485 dirty_region_reset ();
486 dirty_region_add (0, 0, mode_info
.width
, mode_info
.height
);
488 return (grub_errno
= GRUB_ERR_NONE
);
492 grub_gfxterm_fini (void)
496 grub_video_bitmap_destroy (bitmap
);
500 grub_virtual_screen_free ();
502 grub_video_restore ();
504 return GRUB_ERR_NONE
;
508 redraw_screen_rect (unsigned int x
, unsigned int y
,
509 unsigned int width
, unsigned int height
)
511 grub_video_color_t color
;
513 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
518 /* Render bitmap as background. */
519 grub_video_blit_bitmap (bitmap
, GRUB_VIDEO_BLIT_REPLACE
, x
, y
,
523 /* If bitmap is smaller than requested blit area, use background
525 color
= virtual_screen
.bg_color
;
527 /* Fill right side of the bitmap if needed. */
528 if ((x
+ width
>= bitmap_width
) && (y
< bitmap_height
))
530 int w
= (x
+ width
) - bitmap_width
;
534 if (y
+ height
>= bitmap_height
)
536 h
= bitmap_height
- y
;
539 if (bitmap_width
> tx
)
544 /* Render background layer. */
545 grub_video_fill_rect (color
, tx
, y
, w
, h
);
548 /* Fill bottom side of the bitmap if needed. */
549 if (y
+ height
>= bitmap_height
)
551 int h
= (y
+ height
) - bitmap_height
;
554 if (bitmap_height
> ty
)
559 /* Render background layer. */
560 grub_video_fill_rect (color
, x
, ty
, width
, h
);
563 /* Render text layer as blended. */
564 grub_video_blit_render_target (text_layer
, GRUB_VIDEO_BLIT_BLEND
, x
, y
,
565 x
- virtual_screen
.offset_x
,
566 y
- virtual_screen
.offset_y
,
571 /* Render background layer. */
572 color
= virtual_screen
.bg_color
;
573 grub_video_fill_rect (color
, x
, y
, width
, height
);
575 /* Render text layer as replaced (to get texts background color). */
576 grub_video_blit_render_target (text_layer
, GRUB_VIDEO_BLIT_REPLACE
, x
, y
,
577 x
- virtual_screen
.offset_x
,
578 y
- virtual_screen
.offset_y
,
584 dirty_region_reset (void)
586 dirty_region
.top_left_x
= -1;
587 dirty_region
.top_left_y
= -1;
588 dirty_region
.bottom_right_x
= -1;
589 dirty_region
.bottom_right_y
= -1;
593 dirty_region_is_empty (void)
595 if ((dirty_region
.top_left_x
== -1)
596 || (dirty_region
.top_left_y
== -1)
597 || (dirty_region
.bottom_right_x
== -1)
598 || (dirty_region
.bottom_right_y
== -1))
604 dirty_region_add (int x
, int y
, unsigned int width
, unsigned int height
)
606 if ((width
== 0) || (height
== 0))
609 if (dirty_region_is_empty ())
611 dirty_region
.top_left_x
= x
;
612 dirty_region
.top_left_y
= y
;
613 dirty_region
.bottom_right_x
= x
+ width
- 1;
614 dirty_region
.bottom_right_y
= y
+ height
- 1;
618 if (x
< dirty_region
.top_left_x
)
619 dirty_region
.top_left_x
= x
;
620 if (y
< dirty_region
.top_left_y
)
621 dirty_region
.top_left_y
= y
;
622 if ((x
+ (int)width
- 1) > dirty_region
.bottom_right_x
)
623 dirty_region
.bottom_right_x
= x
+ width
- 1;
624 if ((y
+ (int)height
- 1) > dirty_region
.bottom_right_y
)
625 dirty_region
.bottom_right_y
= y
+ height
- 1;
630 dirty_region_add_virtualscreen (void)
632 /* Mark virtual screen as dirty. */
633 dirty_region_add (virtual_screen
.offset_x
, virtual_screen
.offset_y
,
634 virtual_screen
.width
, virtual_screen
.height
);
639 dirty_region_redraw (void)
646 if (dirty_region_is_empty ())
649 x
= dirty_region
.top_left_x
;
650 y
= dirty_region
.top_left_y
;
652 width
= dirty_region
.bottom_right_x
- x
+ 1;
653 height
= dirty_region
.bottom_right_y
- y
+ 1;
655 redraw_screen_rect (x
, y
, width
, height
);
657 dirty_region_reset ();
663 struct grub_colored_char
*p
;
664 struct grub_font_glyph glyph
;
665 grub_video_color_t color
;
666 grub_video_color_t bgcolor
;
670 /* Find out active character. */
671 p
= (virtual_screen
.text_buffer
672 + virtual_screen
.cursor_x
673 + (virtual_screen
.cursor_y
* virtual_screen
.columns
));
677 /* Get glyph for character. */
678 grub_font_get_glyph (p
->code
, &glyph
);
681 bgcolor
= p
->bg_color
;
683 x
= virtual_screen
.cursor_x
* virtual_screen
.char_width
;
684 y
= virtual_screen
.cursor_y
* virtual_screen
.char_height
;
686 /* Render glyph to text layer. */
687 grub_video_set_active_render_target (text_layer
);
688 grub_video_fill_rect (bgcolor
, x
, y
, glyph
.width
, glyph
.height
);
689 grub_video_blit_glyph (&glyph
, color
, x
, y
);
690 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
692 /* Mark character to be drawn. */
693 dirty_region_add (virtual_screen
.offset_x
+ x
, virtual_screen
.offset_y
+ y
,
694 glyph
.width
, glyph
.height
);
704 grub_video_color_t color
;
706 /* Determine cursor properties and position on text layer. */
707 x
= virtual_screen
.cursor_x
* virtual_screen
.char_width
;
708 y
= ((virtual_screen
.cursor_y
+ 1) * virtual_screen
.char_height
) - 3;
709 width
= virtual_screen
.char_width
;
712 color
= virtual_screen
.cursor_color
;
714 /* Render cursor to text layer. */
715 grub_video_set_active_render_target (text_layer
);
716 grub_video_fill_rect (color
, x
, y
, width
, height
);
717 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
719 /* Mark cursor to be redrawn. */
720 dirty_region_add (virtual_screen
.offset_x
+ x
, virtual_screen
.offset_y
+ y
,
728 grub_video_color_t color
;
730 /* If we don't have background bitmap, remove cursor. */
736 /* Redraw only changed regions. */
737 dirty_region_redraw ();
740 /* Scroll text buffer with one line to up. */
741 grub_memmove (virtual_screen
.text_buffer
,
742 virtual_screen
.text_buffer
+ virtual_screen
.columns
,
743 sizeof (*virtual_screen
.text_buffer
)
744 * virtual_screen
.columns
745 * (virtual_screen
.rows
- 1));
747 /* Clear last line in text buffer. */
748 for (i
= virtual_screen
.columns
* (virtual_screen
.rows
- 1);
749 i
< virtual_screen
.columns
* virtual_screen
.rows
;
752 virtual_screen
.text_buffer
[i
].code
= ' ';
753 virtual_screen
.text_buffer
[i
].fg_color
= virtual_screen
.fg_color
;
754 virtual_screen
.text_buffer
[i
].bg_color
= virtual_screen
.bg_color
;
755 virtual_screen
.text_buffer
[i
].width
= 0;
756 virtual_screen
.text_buffer
[i
].index
= 0;
759 /* Scroll physical screen. */
760 grub_video_set_active_render_target (text_layer
);
761 color
= virtual_screen
.bg_color
;
762 grub_video_scroll (color
, 0, -virtual_screen
.char_height
);
763 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
765 /* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */
768 /* Mark virtual screen to be redrawn. */
769 dirty_region_add_virtualscreen ();
773 /* Clear new border area. */
774 grub_video_fill_rect (color
,
775 virtual_screen
.offset_x
, virtual_screen
.offset_y
,
776 virtual_screen
.width
, virtual_screen
.char_height
);
778 /* Scroll physical screen. */
779 grub_video_scroll (color
, 0, -virtual_screen
.char_height
);
781 /* Draw cursor if visible. */
782 if (virtual_screen
.cursor_state
)
788 grub_gfxterm_putchar (grub_uint32_t c
)
794 if (c
== '\b' || c
== '\n' || c
== '\r')
796 /* Erase current cursor, if any. */
797 if (virtual_screen
.cursor_state
)
803 if (virtual_screen
.cursor_x
> 0)
804 virtual_screen
.cursor_x
--;
808 if (virtual_screen
.cursor_y
>= virtual_screen
.rows
- 1)
811 virtual_screen
.cursor_y
++;
815 virtual_screen
.cursor_x
= 0;
819 /* Redraw cursor if visible. */
820 if (virtual_screen
.cursor_state
)
825 struct grub_font_glyph glyph
;
826 struct grub_colored_char
*p
;
828 /* Get properties of the character. */
829 grub_font_get_glyph (c
, &glyph
);
831 /* If we are about to exceed line length, wrap to next line. */
832 if (virtual_screen
.cursor_x
+ glyph
.char_width
> virtual_screen
.columns
)
835 /* Find position on virtual screen, and fill information. */
836 p
= (virtual_screen
.text_buffer
+
837 virtual_screen
.cursor_x
+
838 virtual_screen
.cursor_y
* virtual_screen
.columns
);
840 p
->fg_color
= virtual_screen
.fg_color
;
841 p
->bg_color
= virtual_screen
.bg_color
;
842 p
->width
= glyph
.char_width
- 1;
845 /* If we have large glyph, add fixup info. */
846 if (glyph
.char_width
> 1)
850 for (i
= 1; i
< glyph
.char_width
; i
++)
853 p
[i
].width
= glyph
.char_width
- 1;
861 /* Make sure we scroll screen when needed and wrap line correctly. */
862 virtual_screen
.cursor_x
+= glyph
.char_width
;
863 if (virtual_screen
.cursor_x
>= virtual_screen
.columns
)
865 virtual_screen
.cursor_x
= 0;
867 if (virtual_screen
.cursor_y
>= virtual_screen
.rows
- 1)
870 virtual_screen
.cursor_y
++;
873 /* Draw cursor if visible. */
874 if (virtual_screen
.cursor_state
)
880 grub_gfxterm_getcharwidth (grub_uint32_t c
)
882 struct grub_font_glyph glyph
;
884 grub_font_get_glyph (c
, &glyph
);
886 return glyph
.char_width
;
890 grub_virtual_screen_getwh (void)
892 return (virtual_screen
.columns
<< 8) | virtual_screen
.rows
;
896 grub_virtual_screen_getxy (void)
898 return ((virtual_screen
.cursor_x
<< 8) | virtual_screen
.cursor_y
);
902 grub_gfxterm_gotoxy (grub_uint8_t x
, grub_uint8_t y
)
904 if (x
>= virtual_screen
.columns
)
905 x
= virtual_screen
.columns
- 1;
907 if (y
>= virtual_screen
.rows
)
908 y
= virtual_screen
.rows
- 1;
910 if (virtual_screen
.cursor_state
)
913 virtual_screen
.cursor_x
= x
;
914 virtual_screen
.cursor_y
= y
;
916 if (virtual_screen
.cursor_state
)
921 grub_virtual_screen_cls (void)
925 for (i
= 0; i
< virtual_screen
.columns
* virtual_screen
.rows
; i
++)
927 virtual_screen
.text_buffer
[i
].code
= ' ';
928 virtual_screen
.text_buffer
[i
].fg_color
= virtual_screen
.fg_color
;
929 virtual_screen
.text_buffer
[i
].bg_color
= virtual_screen
.bg_color
;
930 virtual_screen
.text_buffer
[i
].width
= 0;
931 virtual_screen
.text_buffer
[i
].index
= 0;
934 virtual_screen
.cursor_x
= virtual_screen
.cursor_y
= 0;
938 grub_gfxterm_cls (void)
940 grub_video_color_t color
;
942 /* Clear virtual screen. */
943 grub_virtual_screen_cls ();
945 /* Clear text layer. */
946 grub_video_set_active_render_target (text_layer
);
947 color
= virtual_screen
.bg_color
;
948 grub_video_fill_rect (color
, 0, 0, mode_info
.width
, mode_info
.height
);
949 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
951 /* Mark virtual screen to be redrawn. */
952 dirty_region_add_virtualscreen ();
956 grub_virtual_screen_setcolorstate (grub_term_color_state state
)
960 case GRUB_TERM_COLOR_STANDARD
:
961 virtual_screen
.term_color
= virtual_screen
.standard_color_setting
;
964 case GRUB_TERM_COLOR_NORMAL
:
965 virtual_screen
.term_color
= virtual_screen
.normal_color_setting
;
968 case GRUB_TERM_COLOR_HIGHLIGHT
:
969 virtual_screen
.term_color
= virtual_screen
.highlight_color_setting
;
976 /* Change color to virtual terminal. */
977 set_term_color (virtual_screen
.term_color
);
981 grub_virtual_screen_setcolor (grub_uint8_t normal_color
,
982 grub_uint8_t highlight_color
)
984 virtual_screen
.normal_color_setting
= normal_color
;
985 virtual_screen
.highlight_color_setting
= highlight_color
;
989 grub_virtual_screen_getcolor (grub_uint8_t
*normal_color
,
990 grub_uint8_t
*highlight_color
)
992 *normal_color
= virtual_screen
.normal_color_setting
;
993 *highlight_color
= virtual_screen
.highlight_color_setting
;
997 grub_gfxterm_setcursor (int on
)
999 if (virtual_screen
.cursor_state
!= on
)
1001 if (virtual_screen
.cursor_state
)
1006 virtual_screen
.cursor_state
= on
;
1011 grub_gfxterm_refresh (void)
1013 /* Redraw only changed regions. */
1014 dirty_region_redraw ();
1018 grub_gfxterm_background_image_cmd (struct grub_arg_list
*state
__attribute__ ((unused
)),
1022 /* Check that we have video adapter active. */
1023 if (grub_video_get_info(NULL
) != GRUB_ERR_NONE
)
1026 /* Destroy existing background bitmap if loaded. */
1029 grub_video_bitmap_destroy (bitmap
);
1032 /* Mark whole screen as dirty. */
1033 dirty_region_reset ();
1034 dirty_region_add (0, 0, mode_info
.width
, mode_info
.height
);
1037 /* If filename was provided, try to load that. */
1040 /* Try to load new one. */
1041 grub_video_bitmap_load (&bitmap
, args
[0]);
1042 if (grub_errno
!= GRUB_ERR_NONE
)
1045 /* If bitmap was loaded correctly, display it. */
1048 /* Determine bitmap dimensions. */
1049 bitmap_width
= grub_video_bitmap_get_width (bitmap
);
1050 bitmap_height
= grub_video_bitmap_get_width (bitmap
);
1052 /* Mark whole screen as dirty. */
1053 dirty_region_reset ();
1054 dirty_region_add (0, 0, mode_info
.width
, mode_info
.height
);
1059 grub_errno
= GRUB_ERR_NONE
;
1063 static struct grub_term grub_video_term
=
1066 .init
= grub_gfxterm_init
,
1067 .fini
= grub_gfxterm_fini
,
1068 .putchar
= grub_gfxterm_putchar
,
1069 .getcharwidth
= grub_gfxterm_getcharwidth
,
1070 .checkkey
= grub_console_checkkey
,
1071 .getkey
= grub_console_getkey
,
1072 .getwh
= grub_virtual_screen_getwh
,
1073 .getxy
= grub_virtual_screen_getxy
,
1074 .gotoxy
= grub_gfxterm_gotoxy
,
1075 .cls
= grub_gfxterm_cls
,
1076 .setcolorstate
= grub_virtual_screen_setcolorstate
,
1077 .setcolor
= grub_virtual_screen_setcolor
,
1078 .getcolor
= grub_virtual_screen_getcolor
,
1079 .setcursor
= grub_gfxterm_setcursor
,
1080 .refresh
= grub_gfxterm_refresh
,
1085 GRUB_MOD_INIT(term_gfxterm
)
1088 grub_term_register (&grub_video_term
);
1090 grub_register_command ("background_image",
1091 grub_gfxterm_background_image_cmd
,
1092 GRUB_COMMAND_FLAG_BOTH
,
1094 "Load background image for active terminal",
1098 GRUB_MOD_FINI(term_gfxterm
)
1100 grub_unregister_command ("bgimage");
1101 grub_term_unregister (&grub_video_term
);