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:
commit
d9b091d9ff
2 changed files with 116 additions and 59 deletions
18
ChangeLog.gfxtermscroll
Normal file
18
ChangeLog.gfxtermscroll
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
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.
|
||||||
|
|
155
term/gfxterm.c
155
term/gfxterm.c
|
@ -102,6 +102,8 @@ struct grub_virtual_screen
|
||||||
/* Text buffer for virtual screen. Contains (columns * rows) number
|
/* Text buffer for virtual screen. Contains (columns * rows) number
|
||||||
of entries. */
|
of entries. */
|
||||||
struct grub_colored_char *text_buffer;
|
struct grub_colored_char *text_buffer;
|
||||||
|
|
||||||
|
int total_scroll;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grub_gfxterm_window
|
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_x = 0;
|
||||||
virtual_screen.cursor_y = 0;
|
virtual_screen.cursor_y = 0;
|
||||||
virtual_screen.cursor_state = 1;
|
virtual_screen.cursor_state = 1;
|
||||||
|
virtual_screen.total_scroll = 0;
|
||||||
|
|
||||||
/* Calculate size of text buffer. */
|
/* Calculate size of text buffer. */
|
||||||
virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width;
|
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);
|
redraw_screen_rect (x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static inline void
|
||||||
write_char (void)
|
paint_char (unsigned cx, unsigned cy)
|
||||||
{
|
{
|
||||||
struct grub_colored_char *p;
|
struct grub_colored_char *p;
|
||||||
struct grub_font_glyph *glyph;
|
struct grub_font_glyph *glyph;
|
||||||
|
@ -599,10 +602,12 @@ write_char (void)
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
|
|
||||||
|
if (cy + virtual_screen.total_scroll >= virtual_screen.rows)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Find out active character. */
|
/* Find out active character. */
|
||||||
p = (virtual_screen.text_buffer
|
p = (virtual_screen.text_buffer
|
||||||
+ virtual_screen.cursor_x
|
+ cx + (cy * virtual_screen.columns));
|
||||||
+ (virtual_screen.cursor_y * virtual_screen.columns));
|
|
||||||
|
|
||||||
p -= p->index;
|
p -= p->index;
|
||||||
|
|
||||||
|
@ -616,8 +621,8 @@ write_char (void)
|
||||||
color = p->fg_color;
|
color = p->fg_color;
|
||||||
bgcolor = p->bg_color;
|
bgcolor = p->bg_color;
|
||||||
|
|
||||||
x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
|
x = cx * virtual_screen.normal_char_width;
|
||||||
y = virtual_screen.cursor_y * virtual_screen.normal_char_height;
|
y = (cy + virtual_screen.total_scroll) * virtual_screen.normal_char_height;
|
||||||
|
|
||||||
/* Render glyph to text layer. */
|
/* Render glyph to text layer. */
|
||||||
grub_video_set_active_render_target (text_layer);
|
grub_video_set_active_render_target (text_layer);
|
||||||
|
@ -630,64 +635,58 @@ write_char (void)
|
||||||
width, height);
|
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)
|
draw_cursor (int show)
|
||||||
{
|
{
|
||||||
|
unsigned int x;
|
||||||
|
unsigned int y;
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
grub_video_color_t color;
|
||||||
|
|
||||||
write_char ();
|
write_char ();
|
||||||
|
|
||||||
if (show)
|
if (!show)
|
||||||
{
|
return;
|
||||||
unsigned int x;
|
|
||||||
unsigned int y;
|
|
||||||
unsigned int width;
|
|
||||||
unsigned int height;
|
|
||||||
grub_video_color_t color;
|
|
||||||
|
|
||||||
/* Determine cursor properties and position on text layer. */
|
if (virtual_screen.cursor_y + virtual_screen.total_scroll
|
||||||
x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
|
>= virtual_screen.rows)
|
||||||
width = virtual_screen.normal_char_width;
|
return;
|
||||||
color = virtual_screen.fg_color;
|
|
||||||
y = (virtual_screen.cursor_y * virtual_screen.normal_char_height
|
|
||||||
+ grub_font_get_ascent (virtual_screen.font));
|
|
||||||
height = 2;
|
|
||||||
|
|
||||||
/* Render cursor to text layer. */
|
/* Determine cursor properties and position on text layer. */
|
||||||
grub_video_set_active_render_target (text_layer);
|
x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
|
||||||
grub_video_fill_rect (color, x, y, width, height);
|
width = virtual_screen.normal_char_width;
|
||||||
grub_video_set_active_render_target (render_target);
|
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;
|
||||||
|
|
||||||
/* Mark cursor to be redrawn. */
|
/* Render cursor to text layer. */
|
||||||
dirty_region_add (virtual_screen.offset_x + x,
|
grub_video_set_active_render_target (text_layer);
|
||||||
virtual_screen.offset_y + y,
|
grub_video_fill_rect (color, x, y, width, height);
|
||||||
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
|
static void
|
||||||
scroll_up (void)
|
real_scroll (void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i, j, was_scroll;
|
||||||
grub_video_color_t color;
|
grub_video_color_t color;
|
||||||
|
|
||||||
/* If we don't have background bitmap, remove cursor. */
|
if (!virtual_screen.total_scroll)
|
||||||
if (!bitmap)
|
return;
|
||||||
{
|
|
||||||
/* 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 we have bitmap, re-draw screen, otherwise scroll physical screen too. */
|
/* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */
|
||||||
if (bitmap)
|
if (bitmap)
|
||||||
|
@ -695,7 +694,8 @@ scroll_up (void)
|
||||||
/* Scroll physical screen. */
|
/* Scroll physical screen. */
|
||||||
grub_video_set_active_render_target (text_layer);
|
grub_video_set_active_render_target (text_layer);
|
||||||
color = virtual_screen.bg_color;
|
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. */
|
/* Mark virtual screen to be redrawn. */
|
||||||
dirty_region_add_virtualscreen ();
|
dirty_region_add_virtualscreen ();
|
||||||
|
@ -704,6 +704,9 @@ scroll_up (void)
|
||||||
{
|
{
|
||||||
grub_video_rect_t saved_view;
|
grub_video_rect_t saved_view;
|
||||||
|
|
||||||
|
/* Remove cursor. */
|
||||||
|
draw_cursor (0);
|
||||||
|
|
||||||
grub_video_set_active_render_target (render_target);
|
grub_video_set_active_render_target (render_target);
|
||||||
/* Save viewport and set it to our window. */
|
/* Save viewport and set it to our window. */
|
||||||
grub_video_get_viewport ((unsigned *) &saved_view.x,
|
grub_video_get_viewport ((unsigned *) &saved_view.x,
|
||||||
|
@ -723,13 +726,15 @@ scroll_up (void)
|
||||||
virtual_screen.offset_x,
|
virtual_screen.offset_x,
|
||||||
virtual_screen.offset_y,
|
virtual_screen.offset_y,
|
||||||
virtual_screen.width,
|
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);
|
grub_video_set_active_render_target (render_target);
|
||||||
dirty_region_redraw ();
|
dirty_region_redraw ();
|
||||||
|
|
||||||
/* Scroll physical screen. */
|
/* 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)
|
if (i)
|
||||||
grub_video_swap_buffers ();
|
grub_video_swap_buffers ();
|
||||||
|
@ -739,22 +744,54 @@ scroll_up (void)
|
||||||
/* Scroll physical screen. */
|
/* Scroll physical screen. */
|
||||||
grub_video_set_active_render_target (text_layer);
|
grub_video_set_active_render_target (text_layer);
|
||||||
color = virtual_screen.bg_color;
|
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. */
|
/* Restore saved viewport. */
|
||||||
grub_video_set_viewport (saved_view.x, saved_view.y,
|
grub_video_set_viewport (saved_view.x, saved_view.y,
|
||||||
saved_view.width, saved_view.height);
|
saved_view.width, saved_view.height);
|
||||||
grub_video_set_active_render_target (render_target);
|
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)
|
if (repaint_callback)
|
||||||
repaint_callback (window.x, window.y, window.width, window.height);
|
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
|
static void
|
||||||
grub_gfxterm_putchar (grub_uint32_t c)
|
grub_gfxterm_putchar (grub_uint32_t c)
|
||||||
{
|
{
|
||||||
|
@ -1023,6 +1060,8 @@ grub_gfxterm_setcursor (int on)
|
||||||
static void
|
static void
|
||||||
grub_gfxterm_refresh (void)
|
grub_gfxterm_refresh (void)
|
||||||
{
|
{
|
||||||
|
real_scroll ();
|
||||||
|
|
||||||
/* Redraw only changed regions. */
|
/* Redraw only changed regions. */
|
||||||
dirty_region_redraw ();
|
dirty_region_redraw ();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue