2009-11-30 Vladimir Serbinenko <phcoder@gmail.com>
Agglomerate scrolling in gfxterm. * term/gfxterm.c (grub_virtual_screen): New member 'total_screen'. (grub_virtual_screen_setup): Initialise 'total_screen'. (write_char): Split to ... (paint_char): ... this ... (write_char): ... and this. (paint_char): Handle delayed scrolling. (draw_cursor): Likewise. (scroll_up): Split to ... (real_scroll): ... this ... (scroll_up): ... and this. (real_scroll): Handle multi-line scroll and draw below-the-bottom characters. (grub_gfxterm_refresh): Call real_scroll.
This commit is contained in:
parent
9ec25583a9
commit
af20edb21d
1 changed files with 98 additions and 59 deletions
157
term/gfxterm.c
157
term/gfxterm.c
|
@ -102,6 +102,8 @@ struct grub_virtual_screen
|
|||
/* Text buffer for virtual screen. Contains (columns * rows) number
|
||||
of entries. */
|
||||
struct grub_colored_char *text_buffer;
|
||||
|
||||
int total_scroll;
|
||||
};
|
||||
|
||||
struct grub_gfxterm_window
|
||||
|
@ -225,6 +227,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
|
|||
virtual_screen.cursor_x = 0;
|
||||
virtual_screen.cursor_y = 0;
|
||||
virtual_screen.cursor_state = 1;
|
||||
virtual_screen.total_scroll = 0;
|
||||
|
||||
/* Calculate size of text buffer. */
|
||||
virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width;
|
||||
|
@ -586,8 +589,8 @@ dirty_region_redraw (void)
|
|||
redraw_screen_rect (x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
write_char (void)
|
||||
static inline void
|
||||
paint_char (unsigned cx, unsigned cy)
|
||||
{
|
||||
struct grub_colored_char *p;
|
||||
struct grub_font_glyph *glyph;
|
||||
|
@ -599,10 +602,12 @@ write_char (void)
|
|||
unsigned int height;
|
||||
unsigned int width;
|
||||
|
||||
if (cy + virtual_screen.total_scroll >= virtual_screen.rows)
|
||||
return;
|
||||
|
||||
/* Find out active character. */
|
||||
p = (virtual_screen.text_buffer
|
||||
+ virtual_screen.cursor_x
|
||||
+ (virtual_screen.cursor_y * virtual_screen.columns));
|
||||
+ cx + (cy * virtual_screen.columns));
|
||||
|
||||
p -= p->index;
|
||||
|
||||
|
@ -616,8 +621,8 @@ write_char (void)
|
|||
color = p->fg_color;
|
||||
bgcolor = p->bg_color;
|
||||
|
||||
x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
|
||||
y = virtual_screen.cursor_y * virtual_screen.normal_char_height;
|
||||
x = cx * virtual_screen.normal_char_width;
|
||||
y = (cy + virtual_screen.total_scroll) * virtual_screen.normal_char_height;
|
||||
|
||||
/* Render glyph to text layer. */
|
||||
grub_video_set_active_render_target (text_layer);
|
||||
|
@ -630,64 +635,58 @@ write_char (void)
|
|||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
static inline void
|
||||
write_char (void)
|
||||
{
|
||||
paint_char (virtual_screen.cursor_x, virtual_screen.cursor_y);
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_cursor (int show)
|
||||
{
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
grub_video_color_t color;
|
||||
|
||||
write_char ();
|
||||
|
||||
if (show)
|
||||
{
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
grub_video_color_t color;
|
||||
if (!show)
|
||||
return;
|
||||
|
||||
/* Determine cursor properties and position on text layer. */
|
||||
x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
|
||||
width = virtual_screen.normal_char_width;
|
||||
color = virtual_screen.fg_color;
|
||||
y = (virtual_screen.cursor_y * virtual_screen.normal_char_height
|
||||
+ grub_font_get_ascent (virtual_screen.font));
|
||||
height = 2;
|
||||
if (virtual_screen.cursor_y + virtual_screen.total_scroll
|
||||
>= virtual_screen.rows)
|
||||
return;
|
||||
|
||||
/* Render cursor to text layer. */
|
||||
grub_video_set_active_render_target (text_layer);
|
||||
grub_video_fill_rect (color, x, y, width, height);
|
||||
grub_video_set_active_render_target (render_target);
|
||||
|
||||
/* Mark cursor to be redrawn. */
|
||||
dirty_region_add (virtual_screen.offset_x + x,
|
||||
virtual_screen.offset_y + y,
|
||||
width, height);
|
||||
}
|
||||
/* Determine cursor properties and position on text layer. */
|
||||
x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
|
||||
width = virtual_screen.normal_char_width;
|
||||
color = virtual_screen.fg_color;
|
||||
y = ((virtual_screen.cursor_y + virtual_screen.total_scroll)
|
||||
* virtual_screen.normal_char_height
|
||||
+ grub_font_get_ascent (virtual_screen.font));
|
||||
height = 2;
|
||||
|
||||
/* Render cursor to text layer. */
|
||||
grub_video_set_active_render_target (text_layer);
|
||||
grub_video_fill_rect (color, x, y, width, height);
|
||||
grub_video_set_active_render_target (render_target);
|
||||
|
||||
/* Mark cursor to be redrawn. */
|
||||
dirty_region_add (virtual_screen.offset_x + x,
|
||||
virtual_screen.offset_y + y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
scroll_up (void)
|
||||
real_scroll (void)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i, j, was_scroll;
|
||||
grub_video_color_t color;
|
||||
|
||||
/* If we don't have background bitmap, remove cursor. */
|
||||
if (!bitmap)
|
||||
{
|
||||
/* Remove cursor. */
|
||||
draw_cursor (0);
|
||||
}
|
||||
|
||||
/* Scroll text buffer with one line to up. */
|
||||
grub_memmove (virtual_screen.text_buffer,
|
||||
virtual_screen.text_buffer + virtual_screen.columns,
|
||||
sizeof (*virtual_screen.text_buffer)
|
||||
* virtual_screen.columns
|
||||
* (virtual_screen.rows - 1));
|
||||
|
||||
/* Clear last line in text buffer. */
|
||||
for (i = virtual_screen.columns * (virtual_screen.rows - 1);
|
||||
i < virtual_screen.columns * virtual_screen.rows;
|
||||
i++)
|
||||
clear_char (&(virtual_screen.text_buffer[i]));
|
||||
if (!virtual_screen.total_scroll)
|
||||
return;
|
||||
|
||||
/* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */
|
||||
if (bitmap)
|
||||
|
@ -695,7 +694,8 @@ scroll_up (void)
|
|||
/* Scroll physical screen. */
|
||||
grub_video_set_active_render_target (text_layer);
|
||||
color = virtual_screen.bg_color;
|
||||
grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
|
||||
grub_video_scroll (color, 0, -virtual_screen.normal_char_height
|
||||
* virtual_screen.total_scroll);
|
||||
|
||||
/* Mark virtual screen to be redrawn. */
|
||||
dirty_region_add_virtualscreen ();
|
||||
|
@ -704,6 +704,9 @@ scroll_up (void)
|
|||
{
|
||||
grub_video_rect_t saved_view;
|
||||
|
||||
/* Remove cursor. */
|
||||
draw_cursor (0);
|
||||
|
||||
grub_video_set_active_render_target (render_target);
|
||||
/* Save viewport and set it to our window. */
|
||||
grub_video_get_viewport ((unsigned *) &saved_view.x,
|
||||
|
@ -723,13 +726,15 @@ scroll_up (void)
|
|||
virtual_screen.offset_x,
|
||||
virtual_screen.offset_y,
|
||||
virtual_screen.width,
|
||||
virtual_screen.normal_char_height);
|
||||
virtual_screen.normal_char_height
|
||||
* virtual_screen.total_scroll);
|
||||
|
||||
grub_video_set_active_render_target (render_target);
|
||||
dirty_region_redraw ();
|
||||
|
||||
/* Scroll physical screen. */
|
||||
grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
|
||||
grub_video_scroll (color, 0, -virtual_screen.normal_char_height
|
||||
* virtual_screen.total_scroll);
|
||||
|
||||
if (i)
|
||||
grub_video_swap_buffers ();
|
||||
|
@ -739,22 +744,54 @@ scroll_up (void)
|
|||
/* Scroll physical screen. */
|
||||
grub_video_set_active_render_target (text_layer);
|
||||
color = virtual_screen.bg_color;
|
||||
grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
|
||||
grub_video_scroll (color, 0, -virtual_screen.normal_char_height
|
||||
* virtual_screen.total_scroll);
|
||||
|
||||
/* Restore saved viewport. */
|
||||
grub_video_set_viewport (saved_view.x, saved_view.y,
|
||||
saved_view.width, saved_view.height);
|
||||
grub_video_set_active_render_target (render_target);
|
||||
|
||||
/* Draw cursor if visible. */
|
||||
if (virtual_screen.cursor_state)
|
||||
draw_cursor (1);
|
||||
}
|
||||
|
||||
/* Draw cursor if visible. */
|
||||
if (virtual_screen.cursor_state)
|
||||
draw_cursor (1);
|
||||
|
||||
was_scroll = virtual_screen.total_scroll;
|
||||
virtual_screen.total_scroll = 0;
|
||||
|
||||
/* Draw shadow part. */
|
||||
for (i = virtual_screen.rows - was_scroll;
|
||||
i < virtual_screen.rows; i++)
|
||||
for (j = 0; j < virtual_screen.columns; j++)
|
||||
paint_char (j, i);
|
||||
|
||||
if (repaint_callback)
|
||||
repaint_callback (window.x, window.y, window.width, window.height);
|
||||
}
|
||||
|
||||
static void
|
||||
scroll_up (void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Scroll text buffer with one line to up. */
|
||||
grub_memmove (virtual_screen.text_buffer,
|
||||
virtual_screen.text_buffer + virtual_screen.columns,
|
||||
sizeof (*virtual_screen.text_buffer)
|
||||
* virtual_screen.columns
|
||||
* (virtual_screen.rows - 1));
|
||||
|
||||
/* Clear last line in text buffer. */
|
||||
for (i = virtual_screen.columns * (virtual_screen.rows - 1);
|
||||
i < virtual_screen.columns * virtual_screen.rows;
|
||||
i++)
|
||||
clear_char (&(virtual_screen.text_buffer[i]));
|
||||
|
||||
virtual_screen.total_scroll++;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_gfxterm_putchar (grub_uint32_t c)
|
||||
{
|
||||
|
@ -1023,6 +1060,8 @@ grub_gfxterm_setcursor (int on)
|
|||
static void
|
||||
grub_gfxterm_refresh (void)
|
||||
{
|
||||
real_scroll ();
|
||||
|
||||
/* Redraw only changed regions. */
|
||||
dirty_region_redraw ();
|
||||
|
||||
|
|
Loading…
Reference in a new issue