2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2006,2007,2008,2009 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/term.h>
20 #include <grub/types.h>
22 #include <grub/misc.h>
23 #include <grub/font.h>
26 #include <grub/video.h>
27 #include <grub/bitmap.h>
28 #include <grub/command.h>
30 #define DEFAULT_VIDEO_MODE "1024x768,800x600,640x480"
31 #define DEFAULT_BORDER_WIDTH 10
33 #define DEFAULT_STANDARD_COLOR 0x07
34 #define DEFAULT_NORMAL_COLOR 0x07
35 #define DEFAULT_HIGHLIGHT_COLOR 0x70
37 struct grub_dirty_region
45 struct grub_colored_char
47 /* An Unicode codepoint. */
51 grub_video_color_t fg_color
;
52 grub_video_color_t bg_color
;
54 /* The width of this character minus one. */
57 /* The column index of this character. */
61 struct grub_virtual_screen
63 /* Dimensions of the virtual screen in pixels. */
67 /* Offset in the display in pixels. */
68 unsigned int offset_x
;
69 unsigned int offset_y
;
71 /* TTY Character sizes in pixes. */
72 unsigned int normal_char_width
;
73 unsigned int normal_char_height
;
75 /* Virtual screen TTY size in characters. */
79 /* Current cursor location in characters. */
80 unsigned int cursor_x
;
81 unsigned int cursor_y
;
83 /* Current cursor state. */
89 /* Terminal color settings. */
90 grub_uint8_t standard_color_setting
;
91 grub_uint8_t normal_color_setting
;
92 grub_uint8_t highlight_color_setting
;
93 grub_uint8_t term_color
;
96 grub_video_color_t fg_color
;
97 grub_video_color_t bg_color
;
99 /* Text buffer for virtual screen. Contains (columns * rows) number
101 struct grub_colored_char
*text_buffer
;
104 static struct grub_virtual_screen virtual_screen
;
106 static struct grub_video_mode_info mode_info
;
108 static struct grub_video_render_target
*text_layer
;
110 static unsigned int bitmap_width
;
111 static unsigned int bitmap_height
;
112 static struct grub_video_bitmap
*bitmap
;
114 static struct grub_dirty_region dirty_region
;
116 static void dirty_region_reset (void);
118 static int dirty_region_is_empty (void);
120 static void dirty_region_add (int x
, int y
,
121 unsigned int width
, unsigned int height
);
123 static unsigned int calculate_normal_character_width (grub_font_t font
);
125 static unsigned char calculate_character_width (struct grub_font_glyph
*glyph
);
128 set_term_color (grub_uint8_t term_color
)
130 struct grub_video_render_target
*old_target
;
132 /* Save previous target and switch to text layer. */
133 grub_video_get_active_render_target (&old_target
);
134 grub_video_set_active_render_target (text_layer
);
136 /* Map terminal color to text layer compatible video colors. */
137 virtual_screen
.fg_color
= grub_video_map_color(term_color
& 0x0f);
139 /* Special case: use black as transparent color. */
140 if (((term_color
>> 4) & 0x0f) == 0)
142 virtual_screen
.bg_color
= grub_video_map_rgba(0, 0, 0, 0);
146 virtual_screen
.bg_color
= grub_video_map_color((term_color
>> 4) & 0x0f);
149 /* Restore previous target. */
150 grub_video_set_active_render_target (old_target
);
154 grub_virtual_screen_free (void)
156 /* If virtual screen has been allocated, free it. */
157 if (virtual_screen
.text_buffer
!= 0)
158 grub_free (virtual_screen
.text_buffer
);
160 /* Reset virtual screen data. */
161 grub_memset (&virtual_screen
, 0, sizeof (virtual_screen
));
163 /* Free render targets. */
164 grub_video_delete_render_target (text_layer
);
169 grub_virtual_screen_setup (unsigned int x
, unsigned int y
,
170 unsigned int width
, unsigned int height
,
171 const char *font_name
)
173 /* Free old virtual screen. */
174 grub_virtual_screen_free ();
176 /* Initialize with default data. */
177 virtual_screen
.font
= grub_font_get (font_name
);
178 if (!virtual_screen
.font
)
179 return grub_error (GRUB_ERR_BAD_FONT
,
181 virtual_screen
.width
= width
;
182 virtual_screen
.height
= height
;
183 virtual_screen
.offset_x
= x
;
184 virtual_screen
.offset_y
= y
;
185 virtual_screen
.normal_char_width
=
186 calculate_normal_character_width (virtual_screen
.font
);
187 virtual_screen
.normal_char_height
=
188 grub_font_get_max_char_height (virtual_screen
.font
);
189 virtual_screen
.cursor_x
= 0;
190 virtual_screen
.cursor_y
= 0;
191 virtual_screen
.cursor_state
= 1;
193 /* Calculate size of text buffer. */
194 virtual_screen
.columns
= virtual_screen
.width
/ virtual_screen
.normal_char_width
;
195 virtual_screen
.rows
= virtual_screen
.height
/ virtual_screen
.normal_char_height
;
197 /* Allocate memory for text buffer. */
198 virtual_screen
.text_buffer
=
199 (struct grub_colored_char
*) grub_malloc (virtual_screen
.columns
200 * virtual_screen
.rows
201 * sizeof (*virtual_screen
.text_buffer
));
202 if (grub_errno
!= GRUB_ERR_NONE
)
205 /* Create new render target for text layer. */
206 grub_video_create_render_target (&text_layer
,
207 virtual_screen
.width
,
208 virtual_screen
.height
,
209 GRUB_VIDEO_MODE_TYPE_RGB
210 | GRUB_VIDEO_MODE_TYPE_ALPHA
);
211 if (grub_errno
!= GRUB_ERR_NONE
)
214 /* As we want to have colors compatible with rendering target,
215 we can only have those after mode is initialized. */
216 grub_video_set_active_render_target (text_layer
);
218 virtual_screen
.standard_color_setting
= DEFAULT_STANDARD_COLOR
;
219 virtual_screen
.normal_color_setting
= DEFAULT_NORMAL_COLOR
;
220 virtual_screen
.highlight_color_setting
= DEFAULT_HIGHLIGHT_COLOR
;
222 virtual_screen
.term_color
= virtual_screen
.normal_color_setting
;
224 set_term_color (virtual_screen
.term_color
);
226 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
231 static int NESTED_FUNC_ATTR
video_hook (grub_video_adapter_t p
__attribute__ ((unused
)),
232 struct grub_video_mode_info
*info
)
234 return ! (info
->mode_type
& GRUB_VIDEO_MODE_TYPE_PURE_TEXT
);
238 grub_gfxterm_init (void)
243 grub_video_color_t color
;
248 /* Select the font to use. */
249 font_name
= grub_env_get ("gfxterm_font");
251 font_name
= ""; /* Allow fallback to any font. */
253 /* Parse gfxmode environment variable if set. */
254 modevar
= grub_env_get ("gfxmode");
255 if (! modevar
|| *modevar
== 0)
256 err
= grub_video_set_mode (DEFAULT_VIDEO_MODE
, video_hook
);
259 tmp
= grub_malloc (grub_strlen (modevar
)
260 + sizeof (DEFAULT_VIDEO_MODE
) + 1);
261 grub_sprintf (tmp
, "%s;" DEFAULT_VIDEO_MODE
, modevar
);
262 err
= grub_video_set_mode (tmp
, video_hook
);
269 err
= grub_video_get_info (&mode_info
);
270 /* Figure out what mode we ended up. */
274 /* Make sure screen is black. */
275 color
= grub_video_map_rgb (0, 0, 0);
276 grub_video_fill_rect (color
, 0, 0, mode_info
.width
, mode_info
.height
);
279 /* Leave borders for virtual screen. */
280 width
= mode_info
.width
- (2 * DEFAULT_BORDER_WIDTH
);
281 height
= mode_info
.height
- (2 * DEFAULT_BORDER_WIDTH
);
283 /* Create virtual screen. */
284 if (grub_virtual_screen_setup (DEFAULT_BORDER_WIDTH
, DEFAULT_BORDER_WIDTH
,
285 width
, height
, font_name
) != GRUB_ERR_NONE
)
287 grub_video_restore ();
291 /* Mark whole screen as dirty. */
292 dirty_region_reset ();
293 dirty_region_add (0, 0, mode_info
.width
, mode_info
.height
);
295 return (grub_errno
= GRUB_ERR_NONE
);
299 grub_gfxterm_fini (void)
303 grub_video_bitmap_destroy (bitmap
);
307 grub_virtual_screen_free ();
309 grub_video_restore ();
311 return GRUB_ERR_NONE
;
315 redraw_screen_rect (unsigned int x
, unsigned int y
,
316 unsigned int width
, unsigned int height
)
318 grub_video_color_t color
;
320 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
325 /* Render bitmap as background. */
326 grub_video_blit_bitmap (bitmap
, GRUB_VIDEO_BLIT_REPLACE
, x
, y
,
330 /* If bitmap is smaller than requested blit area, use background
332 color
= virtual_screen
.bg_color
;
334 /* Fill right side of the bitmap if needed. */
335 if ((x
+ width
>= bitmap_width
) && (y
< bitmap_height
))
337 int w
= (x
+ width
) - bitmap_width
;
341 if (y
+ height
>= bitmap_height
)
343 h
= bitmap_height
- y
;
346 if (bitmap_width
> tx
)
351 /* Render background layer. */
352 grub_video_fill_rect (color
, tx
, y
, w
, h
);
355 /* Fill bottom side of the bitmap if needed. */
356 if (y
+ height
>= bitmap_height
)
358 int h
= (y
+ height
) - bitmap_height
;
361 if (bitmap_height
> ty
)
366 /* Render background layer. */
367 grub_video_fill_rect (color
, x
, ty
, width
, h
);
370 /* Render text layer as blended. */
371 grub_video_blit_render_target (text_layer
, GRUB_VIDEO_BLIT_BLEND
, x
, y
,
372 x
- virtual_screen
.offset_x
,
373 y
- virtual_screen
.offset_y
,
378 /* Render background layer. */
379 color
= virtual_screen
.bg_color
;
380 grub_video_fill_rect (color
, x
, y
, width
, height
);
382 /* Render text layer as replaced (to get texts background color). */
383 grub_video_blit_render_target (text_layer
, GRUB_VIDEO_BLIT_REPLACE
, x
, y
,
384 x
- virtual_screen
.offset_x
,
385 y
- virtual_screen
.offset_y
,
391 dirty_region_reset (void)
393 dirty_region
.top_left_x
= -1;
394 dirty_region
.top_left_y
= -1;
395 dirty_region
.bottom_right_x
= -1;
396 dirty_region
.bottom_right_y
= -1;
400 dirty_region_is_empty (void)
402 if ((dirty_region
.top_left_x
== -1)
403 || (dirty_region
.top_left_y
== -1)
404 || (dirty_region
.bottom_right_x
== -1)
405 || (dirty_region
.bottom_right_y
== -1))
411 dirty_region_add (int x
, int y
, unsigned int width
, unsigned int height
)
413 if ((width
== 0) || (height
== 0))
416 if (dirty_region_is_empty ())
418 dirty_region
.top_left_x
= x
;
419 dirty_region
.top_left_y
= y
;
420 dirty_region
.bottom_right_x
= x
+ width
- 1;
421 dirty_region
.bottom_right_y
= y
+ height
- 1;
425 if (x
< dirty_region
.top_left_x
)
426 dirty_region
.top_left_x
= x
;
427 if (y
< dirty_region
.top_left_y
)
428 dirty_region
.top_left_y
= y
;
429 if ((x
+ (int)width
- 1) > dirty_region
.bottom_right_x
)
430 dirty_region
.bottom_right_x
= x
+ width
- 1;
431 if ((y
+ (int)height
- 1) > dirty_region
.bottom_right_y
)
432 dirty_region
.bottom_right_y
= y
+ height
- 1;
437 dirty_region_add_virtualscreen (void)
439 /* Mark virtual screen as dirty. */
440 dirty_region_add (virtual_screen
.offset_x
, virtual_screen
.offset_y
,
441 virtual_screen
.width
, virtual_screen
.height
);
446 dirty_region_redraw (void)
453 if (dirty_region_is_empty ())
456 x
= dirty_region
.top_left_x
;
457 y
= dirty_region
.top_left_y
;
459 width
= dirty_region
.bottom_right_x
- x
+ 1;
460 height
= dirty_region
.bottom_right_y
- y
+ 1;
462 redraw_screen_rect (x
, y
, width
, height
);
464 dirty_region_reset ();
470 struct grub_colored_char
*p
;
471 struct grub_font_glyph
*glyph
;
472 grub_video_color_t color
;
473 grub_video_color_t bgcolor
;
480 /* Find out active character. */
481 p
= (virtual_screen
.text_buffer
482 + virtual_screen
.cursor_x
483 + (virtual_screen
.cursor_y
* virtual_screen
.columns
));
487 /* Get glyph for character. */
488 glyph
= grub_font_get_glyph (virtual_screen
.font
, p
->code
);
489 ascent
= grub_font_get_ascent (virtual_screen
.font
);
491 width
= virtual_screen
.normal_char_width
* calculate_character_width(glyph
);
492 height
= virtual_screen
.normal_char_height
;
495 bgcolor
= p
->bg_color
;
497 x
= virtual_screen
.cursor_x
* virtual_screen
.normal_char_width
;
498 y
= virtual_screen
.cursor_y
* virtual_screen
.normal_char_height
;
500 /* Render glyph to text layer. */
501 grub_video_set_active_render_target (text_layer
);
502 grub_video_fill_rect (bgcolor
, x
, y
, width
, height
);
503 grub_font_draw_glyph (glyph
, color
, x
, y
+ ascent
);
504 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
506 /* Mark character to be drawn. */
507 dirty_region_add (virtual_screen
.offset_x
+ x
, virtual_screen
.offset_y
+ y
,
512 draw_cursor (int show
)
522 grub_video_color_t color
;
524 /* Determine cursor properties and position on text layer. */
525 x
= virtual_screen
.cursor_x
* virtual_screen
.normal_char_width
;
526 width
= virtual_screen
.normal_char_width
;
527 color
= virtual_screen
.fg_color
;
528 y
= (virtual_screen
.cursor_y
* virtual_screen
.normal_char_height
529 + grub_font_get_ascent (virtual_screen
.font
));
532 /* Render cursor to text layer. */
533 grub_video_set_active_render_target (text_layer
);
534 grub_video_fill_rect (color
, x
, y
, width
, height
);
535 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
537 /* Mark cursor to be redrawn. */
538 dirty_region_add (virtual_screen
.offset_x
+ x
,
539 virtual_screen
.offset_y
+ y
,
548 grub_video_color_t color
;
550 /* If we don't have background bitmap, remove cursor. */
556 /* Redraw only changed regions. */
557 dirty_region_redraw ();
560 /* Scroll text buffer with one line to up. */
561 grub_memmove (virtual_screen
.text_buffer
,
562 virtual_screen
.text_buffer
+ virtual_screen
.columns
,
563 sizeof (*virtual_screen
.text_buffer
)
564 * virtual_screen
.columns
565 * (virtual_screen
.rows
- 1));
567 /* Clear last line in text buffer. */
568 for (i
= virtual_screen
.columns
* (virtual_screen
.rows
- 1);
569 i
< virtual_screen
.columns
* virtual_screen
.rows
;
572 virtual_screen
.text_buffer
[i
].code
= ' ';
573 virtual_screen
.text_buffer
[i
].fg_color
= virtual_screen
.fg_color
;
574 virtual_screen
.text_buffer
[i
].bg_color
= virtual_screen
.bg_color
;
575 virtual_screen
.text_buffer
[i
].width
= 0;
576 virtual_screen
.text_buffer
[i
].index
= 0;
579 /* Scroll physical screen. */
580 grub_video_set_active_render_target (text_layer
);
581 color
= virtual_screen
.bg_color
;
582 grub_video_scroll (color
, 0, -virtual_screen
.normal_char_height
);
583 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
585 /* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */
588 /* Mark virtual screen to be redrawn. */
589 dirty_region_add_virtualscreen ();
593 /* Clear new border area. */
594 grub_video_fill_rect (color
,
595 virtual_screen
.offset_x
, virtual_screen
.offset_y
,
596 virtual_screen
.width
, virtual_screen
.normal_char_height
);
598 /* Scroll physical screen. */
599 grub_video_scroll (color
, 0, -virtual_screen
.normal_char_height
);
601 /* Draw cursor if visible. */
602 if (virtual_screen
.cursor_state
)
608 grub_gfxterm_putchar (grub_uint32_t c
)
614 /* Erase current cursor, if any. */
615 if (virtual_screen
.cursor_state
)
618 if (c
== '\b' || c
== '\n' || c
== '\r')
623 if (virtual_screen
.cursor_x
> 0)
624 virtual_screen
.cursor_x
--;
628 if (virtual_screen
.cursor_y
>= virtual_screen
.rows
- 1)
631 virtual_screen
.cursor_y
++;
635 virtual_screen
.cursor_x
= 0;
641 struct grub_font_glyph
*glyph
;
642 struct grub_colored_char
*p
;
643 unsigned char char_width
;
645 /* Get properties of the character. */
646 glyph
= grub_font_get_glyph (virtual_screen
.font
, c
);
648 /* Calculate actual character width for glyph. This is number of
649 times of normal_font_width. */
650 char_width
= calculate_character_width(glyph
);
652 /* If we are about to exceed line length, wrap to next line. */
653 if (virtual_screen
.cursor_x
+ char_width
> virtual_screen
.columns
)
656 /* Find position on virtual screen, and fill information. */
657 p
= (virtual_screen
.text_buffer
+
658 virtual_screen
.cursor_x
+
659 virtual_screen
.cursor_y
* virtual_screen
.columns
);
661 p
->fg_color
= virtual_screen
.fg_color
;
662 p
->bg_color
= virtual_screen
.bg_color
;
663 p
->width
= char_width
- 1;
666 /* If we have large glyph, add fixup info. */
671 for (i
= 1; i
< char_width
; i
++)
674 p
[i
].width
= char_width
- 1;
682 /* Make sure we scroll screen when needed and wrap line correctly. */
683 virtual_screen
.cursor_x
+= char_width
;
684 if (virtual_screen
.cursor_x
>= virtual_screen
.columns
)
686 virtual_screen
.cursor_x
= 0;
688 if (virtual_screen
.cursor_y
>= virtual_screen
.rows
- 1)
691 virtual_screen
.cursor_y
++;
695 /* Redraw cursor if it should be visible. */
696 /* Note: This will redraw the character as well, which means that the
697 above call to write_char is redundant when the cursor is showing. */
698 if (virtual_screen
.cursor_state
)
702 /* Use ASCII characters to determine normal character width. */
704 calculate_normal_character_width (grub_font_t font
)
706 struct grub_font_glyph
*glyph
;
707 unsigned int width
= 0;
710 /* Get properties of every printable ASCII character. */
711 for (i
= 32; i
< 127; i
++)
713 glyph
= grub_font_get_glyph (font
, i
);
715 /* Skip unknown characters. Should never happen on normal conditions. */
719 if (glyph
->device_width
> width
)
720 width
= glyph
->device_width
;
727 calculate_character_width (struct grub_font_glyph
*glyph
)
729 if (! glyph
|| glyph
->device_width
== 0)
732 return (glyph
->device_width
733 + (virtual_screen
.normal_char_width
- 1))
734 / virtual_screen
.normal_char_width
;
738 grub_gfxterm_getcharwidth (grub_uint32_t c
)
740 struct grub_font_glyph
*glyph
;
741 unsigned char char_width
;
743 /* Get properties of the character. */
744 glyph
= grub_font_get_glyph (virtual_screen
.font
, c
);
746 /* Calculate actual character width for glyph. */
747 char_width
= calculate_character_width (glyph
);
753 grub_virtual_screen_getwh (void)
755 return (virtual_screen
.columns
<< 8) | virtual_screen
.rows
;
759 grub_virtual_screen_getxy (void)
761 return ((virtual_screen
.cursor_x
<< 8) | virtual_screen
.cursor_y
);
765 grub_gfxterm_gotoxy (grub_uint8_t x
, grub_uint8_t y
)
767 if (x
>= virtual_screen
.columns
)
768 x
= virtual_screen
.columns
- 1;
770 if (y
>= virtual_screen
.rows
)
771 y
= virtual_screen
.rows
- 1;
773 /* Erase current cursor, if any. */
774 if (virtual_screen
.cursor_state
)
777 virtual_screen
.cursor_x
= x
;
778 virtual_screen
.cursor_y
= y
;
780 /* Draw cursor if visible. */
781 if (virtual_screen
.cursor_state
)
786 grub_virtual_screen_cls (void)
790 for (i
= 0; i
< virtual_screen
.columns
* virtual_screen
.rows
; i
++)
792 virtual_screen
.text_buffer
[i
].code
= ' ';
793 virtual_screen
.text_buffer
[i
].fg_color
= virtual_screen
.fg_color
;
794 virtual_screen
.text_buffer
[i
].bg_color
= virtual_screen
.bg_color
;
795 virtual_screen
.text_buffer
[i
].width
= 0;
796 virtual_screen
.text_buffer
[i
].index
= 0;
799 virtual_screen
.cursor_x
= virtual_screen
.cursor_y
= 0;
803 grub_gfxterm_cls (void)
805 grub_video_color_t color
;
807 /* Clear virtual screen. */
808 grub_virtual_screen_cls ();
810 /* Clear text layer. */
811 grub_video_set_active_render_target (text_layer
);
812 color
= virtual_screen
.bg_color
;
813 grub_video_fill_rect (color
, 0, 0, mode_info
.width
, mode_info
.height
);
814 grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY
);
816 /* Mark virtual screen to be redrawn. */
817 dirty_region_add_virtualscreen ();
821 grub_virtual_screen_setcolorstate (grub_term_color_state state
)
825 case GRUB_TERM_COLOR_STANDARD
:
826 virtual_screen
.term_color
= virtual_screen
.standard_color_setting
;
829 case GRUB_TERM_COLOR_NORMAL
:
830 virtual_screen
.term_color
= virtual_screen
.normal_color_setting
;
833 case GRUB_TERM_COLOR_HIGHLIGHT
:
834 virtual_screen
.term_color
= virtual_screen
.highlight_color_setting
;
841 /* Change color to virtual terminal. */
842 set_term_color (virtual_screen
.term_color
);
846 grub_virtual_screen_setcolor (grub_uint8_t normal_color
,
847 grub_uint8_t highlight_color
)
849 virtual_screen
.normal_color_setting
= normal_color
;
850 virtual_screen
.highlight_color_setting
= highlight_color
;
854 grub_virtual_screen_getcolor (grub_uint8_t
*normal_color
,
855 grub_uint8_t
*highlight_color
)
857 *normal_color
= virtual_screen
.normal_color_setting
;
858 *highlight_color
= virtual_screen
.highlight_color_setting
;
862 grub_gfxterm_setcursor (int on
)
864 if (virtual_screen
.cursor_state
!= on
)
866 if (virtual_screen
.cursor_state
)
871 virtual_screen
.cursor_state
= on
;
876 grub_gfxterm_refresh (void)
878 /* Redraw only changed regions. */
879 dirty_region_redraw ();
883 grub_gfxterm_background_image_cmd (grub_command_t cmd
__attribute__ ((unused
)),
887 /* Check that we have video adapter active. */
888 if (grub_video_get_info(NULL
) != GRUB_ERR_NONE
)
891 /* Destroy existing background bitmap if loaded. */
894 grub_video_bitmap_destroy (bitmap
);
897 /* Mark whole screen as dirty. */
898 dirty_region_reset ();
899 dirty_region_add (0, 0, mode_info
.width
, mode_info
.height
);
902 /* If filename was provided, try to load that. */
905 /* Try to load new one. */
906 grub_video_bitmap_load (&bitmap
, args
[0]);
907 if (grub_errno
!= GRUB_ERR_NONE
)
910 /* If bitmap was loaded correctly, display it. */
913 /* Determine bitmap dimensions. */
914 bitmap_width
= grub_video_bitmap_get_width (bitmap
);
915 bitmap_height
= grub_video_bitmap_get_width (bitmap
);
917 /* Mark whole screen as dirty. */
918 dirty_region_reset ();
919 dirty_region_add (0, 0, mode_info
.width
, mode_info
.height
);
924 grub_errno
= GRUB_ERR_NONE
;
928 static struct grub_term_output grub_video_term
=
931 .init
= grub_gfxterm_init
,
932 .fini
= grub_gfxterm_fini
,
933 .putchar
= grub_gfxterm_putchar
,
934 .getcharwidth
= grub_gfxterm_getcharwidth
,
935 .getwh
= grub_virtual_screen_getwh
,
936 .getxy
= grub_virtual_screen_getxy
,
937 .gotoxy
= grub_gfxterm_gotoxy
,
938 .cls
= grub_gfxterm_cls
,
939 .setcolorstate
= grub_virtual_screen_setcolorstate
,
940 .setcolor
= grub_virtual_screen_setcolor
,
941 .getcolor
= grub_virtual_screen_getcolor
,
942 .setcursor
= grub_gfxterm_setcursor
,
943 .refresh
= grub_gfxterm_refresh
,
948 static grub_command_t cmd
;
950 GRUB_MOD_INIT(term_gfxterm
)
952 grub_term_register_output ("gfxterm", &grub_video_term
);
953 cmd
= grub_register_command ("background_image",
954 grub_gfxterm_background_image_cmd
,
955 0, "Load background image for active terminal");
958 GRUB_MOD_FINI(term_gfxterm
)
960 grub_unregister_command (cmd
);
961 grub_term_unregister_output (&grub_video_term
);