Important speedup by not redrawing too much

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-11-24 07:17:18 +01:00
parent 4545f150f3
commit 947fa16c8b
11 changed files with 221 additions and 73 deletions

View file

@ -35,6 +35,7 @@
#include <grub/menu_viewer.h> #include <grub/menu_viewer.h>
#include <grub/gfxmenu_model.h> #include <grub/gfxmenu_model.h>
#include <grub/gfxmenu_view.h> #include <grub/gfxmenu_view.h>
#include <grub/time.h>
static void switch_to_text_menu (void) static void switch_to_text_menu (void)
{ {
@ -62,6 +63,7 @@ process_key_press (int c,
{ {
i++; i++;
grub_gfxmenu_model_set_selected_index (model, i); grub_gfxmenu_model_set_selected_index (model, i);
grub_gfxmenu_redraw_menu (view);
} }
} }
break; break;
@ -74,6 +76,7 @@ process_key_press (int c,
{ {
i--; i--;
grub_gfxmenu_model_set_selected_index (model, i); grub_gfxmenu_model_set_selected_index (model, i);
grub_gfxmenu_redraw_menu (view);
} }
} }
break; break;
@ -170,8 +173,14 @@ show_menu (grub_menu_t menu, int nested)
/* Main event loop. */ /* Main event loop. */
int exit_requested = 0; int exit_requested = 0;
grub_gfxmenu_view_draw (view);
grub_video_swap_buffers ();
if (view->double_repaint)
grub_gfxmenu_view_draw (view);
while ((! exit_requested) && (! grub_menu_viewer_should_return ())) while ((! exit_requested) && (! grub_menu_viewer_should_return ()))
{ {
grub_gfxmenu_redraw_timeout (view);
if (grub_gfxmenu_model_timeout_expired (model)) if (grub_gfxmenu_model_timeout_expired (model))
{ {
grub_gfxmenu_model_clear_timeout (model); grub_gfxmenu_model_clear_timeout (model);
@ -181,9 +190,8 @@ show_menu (grub_menu_t menu, int nested)
continue; continue;
} }
grub_gfxmenu_view_draw (view);
grub_video_swap_buffers ();
handle_key_events (model, view, nested, &exit_requested); handle_key_events (model, view, nested, &exit_requested);
grub_cpu_idle ();
} }
grub_gfxmenu_view_destroy (view); grub_gfxmenu_view_destroy (view);

View file

@ -166,7 +166,7 @@ layout_vertically (grub_gui_box_t self, int modify_layout,
} }
static void static void
box_paint (void *vself) box_paint (void *vself, const grub_video_rect_t *region)
{ {
grub_gui_box_t self = vself; grub_gui_box_t self = vself;
struct component_node *cur; struct component_node *cur;
@ -176,7 +176,7 @@ box_paint (void *vself)
for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
{ {
grub_gui_component_t comp = cur->component; grub_gui_component_t comp = cur->component;
comp->ops->paint (comp); comp->ops->paint (comp, region);
} }
grub_gui_restore_viewport (&vpsave); grub_gui_restore_viewport (&vpsave);
} }

View file

@ -79,7 +79,7 @@ canvas_is_instance (void *vself __attribute__((unused)), const char *type)
} }
static void static void
canvas_paint (void *vself) canvas_paint (void *vself, const grub_video_rect_t *region)
{ {
grub_gui_canvas_t self = vself; grub_gui_canvas_t self = vself;
struct component_node *cur; struct component_node *cur;
@ -106,7 +106,8 @@ canvas_paint (void *vself)
} }
/* Paint the child. */ /* Paint the child. */
comp->ops->paint (comp); if (grub_video_have_common_points (region, &r))
comp->ops->paint (comp, region);
} }
grub_gui_restore_viewport (&vpsave); grub_gui_restore_viewport (&vpsave);
} }

View file

@ -112,12 +112,16 @@ check_pixmaps (circular_progress_t self)
} }
static void static void
circprog_paint (void *vself) circprog_paint (void *vself, const grub_video_rect_t *region)
{ {
circular_progress_t self = vself; circular_progress_t self = vself;
if (! self->visible) if (! self->visible)
return; return;
if (!grub_video_have_common_points (region, &self->bounds))
return;
if (! check_pixmaps (self)) if (! check_pixmaps (self))
return; return;

View file

@ -67,12 +67,16 @@ image_is_instance (void *vself __attribute__((unused)), const char *type)
} }
static void static void
image_paint (void *vself) image_paint (void *vself, const grub_video_rect_t *region)
{ {
grub_gui_image_t self = vself; grub_gui_image_t self = vself;
grub_video_rect_t vpsave;
if (! self->bitmap) if (! self->bitmap)
return; return;
grub_video_rect_t vpsave; if (!grub_video_have_common_points (region, &self->bounds))
return;
grub_gui_set_viewport (&self->bounds, &vpsave); grub_gui_set_viewport (&self->bounds, &vpsave);
grub_video_blit_bitmap (self->bitmap, GRUB_VIDEO_BLIT_BLEND, grub_video_blit_bitmap (self->bitmap, GRUB_VIDEO_BLIT_BLEND,
0, 0, 0, 0, 0, 0, 0, 0,

View file

@ -77,13 +77,16 @@ label_is_instance (void *vself __attribute__((unused)), const char *type)
} }
static void static void
label_paint (void *vself) label_paint (void *vself, const grub_video_rect_t *region)
{ {
grub_gui_label_t self = vself; grub_gui_label_t self = vself;
if (! self->visible) if (! self->visible)
return; return;
if (!grub_video_have_common_points (region, &self->bounds))
return;
/* Calculate the starting x coordinate. */ /* Calculate the starting x coordinate. */
int left_x; int left_x;
if (self->align == align_left) if (self->align == align_left)

View file

@ -311,16 +311,18 @@ draw_menu (list_impl_t self)
} }
static void static void
list_paint (void *vself) list_paint (void *vself, const grub_video_rect_t *region)
{ {
list_impl_t self = vself; list_impl_t self = vself;
grub_video_rect_t vpsave;
if (! self->visible) if (! self->visible)
return; return;
if (!grub_video_have_common_points (region, &self->bounds))
return;
check_boxes (self); check_boxes (self);
grub_video_rect_t vpsave;
grub_gui_set_viewport (&self->bounds, &vpsave); grub_gui_set_viewport (&self->bounds, &vpsave);
draw_menu (self); draw_menu (self);
grub_gui_restore_viewport (&vpsave); grub_gui_restore_viewport (&vpsave);

View file

@ -171,11 +171,13 @@ draw_text (grub_gui_progress_bar_t self)
} }
static void static void
progress_bar_paint (void *vself) progress_bar_paint (void *vself, const grub_video_rect_t *region)
{ {
grub_gui_progress_bar_t self = vself; grub_gui_progress_bar_t self = vself;
if (! self->visible) if (! self->visible)
return; return;
if (!grub_video_have_common_points (region, &self->bounds))
return;
grub_video_rect_t vpsave; grub_video_rect_t vpsave;
grub_gui_set_viewport (&self->bounds, &vpsave); grub_gui_set_viewport (&self->bounds, &vpsave);

View file

@ -55,6 +55,8 @@ grub_gfxmenu_view_t
grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model) grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model)
{ {
grub_gfxmenu_view_t view; grub_gfxmenu_view_t view;
grub_err_t err;
struct grub_video_mode_info mode_info;
view = grub_malloc (sizeof (*view)); view = grub_malloc (sizeof (*view));
if (! view) if (! view)
@ -67,6 +69,18 @@ grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model)
(unsigned *) &view->screen.width, (unsigned *) &view->screen.width,
(unsigned *) &view->screen.height); (unsigned *) &view->screen.height);
err = grub_video_get_info (&mode_info);
if (err)
{
grub_free (view);
return 0;
}
else
view->double_repaint = (mode_info.mode_type
& GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
&& !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
/* Clear the screen; there may be garbage left over in video memory, and /* Clear the screen; there may be garbage left over in video memory, and
loading the menu style (particularly the background) can take a while. */ loading the menu style (particularly the background) can take a while. */
grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
@ -97,6 +111,15 @@ grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model)
view->title_text = grub_strdup ("GRUB Boot Menu"); view->title_text = grub_strdup ("GRUB Boot Menu");
view->progress_message_text = 0; view->progress_message_text = 0;
view->theme_path = 0; view->theme_path = 0;
view->last_seconds_remaining = -2;
/* Set the timeout bar's frame. */
view->progress_message_frame.width = view->screen.width * 4 / 5;
view->progress_message_frame.height = 50;
view->progress_message_frame.x = view->screen.x
+ (view->screen.width - view->progress_message_frame.width) / 2;
view->progress_message_frame.y = view->screen.y
+ view->screen.height - 90 - 20 - view->progress_message_frame.height;
if (grub_gfxmenu_view_load_theme (view, theme_path) != 0) if (grub_gfxmenu_view_load_theme (view, theme_path) != 0)
{ {
@ -141,21 +164,23 @@ set_progress_message (grub_gfxmenu_view_t view, const char *message)
} }
static void static void
draw_background (grub_gfxmenu_view_t view) redraw_background (grub_gfxmenu_view_t view,
const grub_video_rect_t *bounds)
{ {
if (view->desktop_image) if (view->desktop_image)
{ {
struct grub_video_bitmap *img = view->desktop_image; struct grub_video_bitmap *img = view->desktop_image;
grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE, grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE,
view->screen.x, view->screen.y, 0, 0, bounds->x, bounds->y,
grub_video_bitmap_get_width (img), bounds->x - view->screen.x,
grub_video_bitmap_get_height (img)); bounds->y - view->screen.y,
bounds->width, bounds->height);
} }
else else
{ {
grub_video_fill_rect (grub_gui_map_color (view->desktop_color), grub_video_fill_rect (grub_gui_map_color (view->desktop_color),
view->screen.x, view->screen.y, bounds->x, bounds->y,
view->screen.width, view->screen.height); bounds->width, bounds->height);
} }
} }
@ -191,6 +216,7 @@ update_timeout_visit (grub_gui_component_t component,
{ {
struct progress_value_data *pv; struct progress_value_data *pv;
pv = (struct progress_value_data *) userdata; pv = (struct progress_value_data *) userdata;
component->ops->set_property (component, "visible", pv->visible); component->ops->set_property (component, "visible", pv->visible);
component->ops->set_property (component, "start", pv->start); component->ops->set_property (component, "start", pv->start);
component->ops->set_property (component, "end", pv->end); component->ops->set_property (component, "end", pv->end);
@ -198,16 +224,43 @@ update_timeout_visit (grub_gui_component_t component,
component->ops->set_property (component, "text", pv->text); component->ops->set_property (component, "text", pv->text);
} }
static void
update_timeout (grub_gfxmenu_view_t view) static inline void
update_timeout (grub_gfxmenu_view_t view, int is_init)
{ {
char startbuf[20]; char startbuf[20];
char valuebuf[20]; char valuebuf[20];
char msgbuf[120]; char msgbuf[120];
int timeout = grub_gfxmenu_model_get_timeout_ms (view->model); int timeout;
int remaining = grub_gfxmenu_model_get_timeout_remaining_ms (view->model); int remaining;
struct progress_value_data pv; struct progress_value_data pv;
int seconds_remaining_rounded_up;
auto void redraw_timeout_visit (grub_gui_component_t component,
void *userdata __attribute__ ((unused)));
auto void redraw_timeout_visit (grub_gui_component_t component,
void *userdata __attribute__ ((unused)))
{
grub_video_rect_t bounds;
component->ops->get_bounds (component, &bounds);
grub_gfxmenu_view_redraw (view, &bounds);
}
timeout = grub_gfxmenu_model_get_timeout_ms (view->model);
if (timeout > 0)
{
remaining = grub_gfxmenu_model_get_timeout_remaining_ms (view->model);
seconds_remaining_rounded_up = (remaining + 999) / 1000;
}
else
seconds_remaining_rounded_up = -1;
if (view->last_seconds_remaining == seconds_remaining_rounded_up && !is_init)
return;
view->last_seconds_remaining = seconds_remaining_rounded_up;
pv.visible = timeout > 0 ? "true" : "false"; pv.visible = timeout > 0 ? "true" : "false";
grub_sprintf (startbuf, "%d", -timeout); grub_sprintf (startbuf, "%d", -timeout);
@ -216,7 +269,6 @@ update_timeout (grub_gfxmenu_view_t view)
grub_sprintf (valuebuf, "%d", remaining > 0 ? -remaining : 0); grub_sprintf (valuebuf, "%d", remaining > 0 ? -remaining : 0);
pv.value = valuebuf; pv.value = valuebuf;
int seconds_remaining_rounded_up = (remaining + 999) / 1000;
grub_sprintf (msgbuf, grub_sprintf (msgbuf,
"The highlighted entry will be booted automatically in %d s.", "The highlighted entry will be booted automatically in %d s.",
seconds_remaining_rounded_up); seconds_remaining_rounded_up);
@ -224,6 +276,21 @@ update_timeout (grub_gfxmenu_view_t view)
grub_gui_find_by_id ((grub_gui_component_t) view->canvas, grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
if (!is_init)
{
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
grub_video_swap_buffers ();
if (view->double_repaint)
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
}
}
void
grub_gfxmenu_redraw_timeout (grub_gfxmenu_view_t view)
{
update_timeout (view, 0);
} }
static void static void
@ -252,19 +319,13 @@ static void
draw_message (grub_gfxmenu_view_t view) draw_message (grub_gfxmenu_view_t view)
{ {
char *text = view->progress_message_text; char *text = view->progress_message_text;
grub_video_rect_t f = view->progress_message_frame;
if (! text) if (! text)
return; return;
grub_font_t font = view->message_font; grub_font_t font = view->message_font;
grub_video_color_t color = grub_gui_map_color (view->message_color); grub_video_color_t color = grub_gui_map_color (view->message_color);
/* Set the timeout bar's frame. */
grub_video_rect_t f;
f.width = view->screen.width * 4 / 5;
f.height = 50;
f.x = view->screen.x + (view->screen.width - f.width) / 2;
f.y = view->screen.y + view->screen.height - 90 - 20 - f.height;
/* Border. */ /* Border. */
grub_video_fill_rect (color, grub_video_fill_rect (color,
f.x-1, f.y-1, f.width+2, f.height+2); f.x-1, f.y-1, f.width+2, f.height+2);
@ -280,19 +341,62 @@ draw_message (grub_gfxmenu_view_t view)
grub_font_draw_string (text, font, color, x, y); grub_font_draw_string (text, font, color, x, y);
} }
void
grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
const grub_video_rect_t *region)
{
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
redraw_background (view, region);
if (view->canvas)
view->canvas->ops->component.paint (view->canvas, region);
draw_title (view);
if (grub_video_have_common_points (&view->progress_message_frame, region))
draw_message (view);
}
void void
grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) grub_gfxmenu_view_draw (grub_gfxmenu_view_t view)
{ {
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); update_timeout (view, 1);
update_timeout (view);
update_menu_components (view); update_menu_components (view);
draw_background (view); grub_gfxmenu_view_redraw (view, &view->screen);
if (view->canvas) grub_video_swap_buffers ();
view->canvas->ops->component.paint (view->canvas); if (view->double_repaint)
draw_title (view); grub_gfxmenu_view_redraw (view, &view->screen);
draw_message (view); }
static void
redraw_menu_visit (grub_gui_component_t component,
void *userdata)
{
grub_gfxmenu_view_t view;
view = userdata;
if (component->ops->is_instance (component, "list"))
{
grub_gui_list_t list;
grub_video_rect_t bounds;
list = (grub_gui_list_t) component;
component->ops->get_bounds (component, &bounds);
grub_gfxmenu_view_redraw (view, &bounds);
}
}
void
grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view)
{
update_menu_components (view);
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
redraw_menu_visit, view);
grub_video_swap_buffers ();
if (view->double_repaint)
{
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
redraw_menu_visit, view);
}
} }
static grub_err_t static grub_err_t
@ -316,7 +420,7 @@ static int term_initialized;
static grub_term_output_t term_original; static grub_term_output_t term_original;
static void static void
draw_terminal_box (void) draw_terminal_box (grub_gfxmenu_view_t view)
{ {
grub_gfxmenu_box_t term_box; grub_gfxmenu_box_t term_box;
int termx; int termx;
@ -335,6 +439,11 @@ draw_terminal_box (void)
term_box->draw (term_box, term_box->draw (term_box,
termx - term_box->get_left_pad (term_box), termx - term_box->get_left_pad (term_box),
termy - term_box->get_top_pad (term_box)); termy - term_box->get_top_pad (term_box));
grub_video_swap_buffers ();
if (view->double_repaint)
term_box->draw (term_box,
termx - term_box->get_left_pad (term_box),
termy - term_box->get_top_pad (term_box));
} }
static void static void
@ -342,9 +451,6 @@ init_terminal (grub_gfxmenu_view_t view)
{ {
int termx; int termx;
int termy; int termy;
struct grub_video_mode_info mode_info;
grub_err_t err;
int double_repaint;
term_original = grub_term_get_current_output (); term_original = grub_term_get_current_output ();
@ -354,34 +460,20 @@ init_terminal (grub_gfxmenu_view_t view)
termx = view->screen.x + view->screen.width * (10 - 7) / 10 / 2; termx = view->screen.x + view->screen.width * (10 - 7) / 10 / 2;
termy = view->screen.y + view->screen.height * (10 - 7) / 10 / 2; termy = view->screen.y + view->screen.height * (10 - 7) / 10 / 2;
err = grub_video_get_info (&mode_info);
if (err)
{
grub_errno = GRUB_ERR_NONE;
double_repaint = 1;
}
else
double_repaint = (mode_info.mode_type
& GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
&& !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
/* Note: currently there is no API for changing the gfxterm font /* Note: currently there is no API for changing the gfxterm font
on the fly, so whatever font the initially loaded theme specifies on the fly, so whatever font the initially loaded theme specifies
will be permanent. */ will be permanent. */
grub_gfxterm_init_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, termx, termy, grub_gfxterm_init_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, termx, termy,
term_target_width, term_target_height, term_target_width, term_target_height,
double_repaint, view->terminal_font_name, 3); view->double_repaint, view->terminal_font_name, 3);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
return; return;
term_initialized = 1; term_initialized = 1;
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
grub_gfxmenu_view_draw (view);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
term_view = view; term_view = view;
grub_term_set_current_output (grub_gfxterm_get_term ()); grub_term_set_current_output (grub_gfxterm_get_term ());
grub_refresh ();
} }
static void destroy_terminal (void) static void destroy_terminal (void)
@ -405,8 +497,10 @@ notify_booting (grub_menu_entry_t entry, void *userdata)
grub_sprintf (s, "Booting '%s'", entry->title); grub_sprintf (s, "Booting '%s'", entry->title);
set_progress_message (view, s); set_progress_message (view, s);
grub_free (s); grub_free (s);
grub_gfxmenu_view_draw (view); grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
grub_video_swap_buffers (); grub_video_swap_buffers ();
if (view->double_repaint)
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
} }
static void static void
@ -421,8 +515,10 @@ notify_fallback (grub_menu_entry_t entry, void *userdata)
grub_sprintf (s, "Falling back to '%s'", entry->title); grub_sprintf (s, "Falling back to '%s'", entry->title);
set_progress_message (view, s); set_progress_message (view, s);
grub_free (s); grub_free (s);
grub_gfxmenu_view_draw (view); grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
grub_video_swap_buffers (); grub_video_swap_buffers ();
if (view->double_repaint)
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
} }
static void static void
@ -442,6 +538,8 @@ int
grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view, grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view,
grub_menu_entry_t entry) grub_menu_entry_t entry)
{ {
draw_terminal_box (view);
grub_menu_execute_with_fallback (grub_gfxmenu_model_get_menu (view->model), grub_menu_execute_with_fallback (grub_gfxmenu_model_get_menu (view->model),
entry, &execute_callback, (void *) view); entry, &execute_callback, (void *) view);
@ -453,7 +551,6 @@ grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view,
"Unable to automatically boot. " "Unable to automatically boot. "
"Press SPACE to continue."); "Press SPACE to continue.");
grub_gfxmenu_view_draw (view); grub_gfxmenu_view_draw (view);
grub_video_swap_buffers ();
while (GRUB_TERM_ASCII_CHAR(grub_getkey ()) != ' ') while (GRUB_TERM_ASCII_CHAR(grub_getkey ()) != ' ')
{ {
/* Wait for SPACE to be pressed. */ /* Wait for SPACE to be pressed. */
@ -461,6 +558,11 @@ grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view,
set_progress_message (view, 0); /* Clear the message. */ set_progress_message (view, 0); /* Clear the message. */
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
grub_video_swap_buffers ();
if (view->double_repaint)
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
return 1; /* Ok. */ return 1; /* Ok. */
} }
@ -468,14 +570,7 @@ int
grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view, grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view,
grub_menu_entry_t entry) grub_menu_entry_t entry)
{ {
/* Currently we switch back to text mode by restoring draw_terminal_box (view);
the original terminal before executing the menu entry.
It is hard to make it work when executing a menu entry
that switches video modes -- it using gfxterm in a
window, the repaint callback seems to crash GRUB. */
/* TODO: Determine if this works when 'gfxterm' was set as
the current terminal before invoking the gfxmenu. */
destroy_terminal ();
grub_menu_execute_entry (entry); grub_menu_execute_entry (entry);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
@ -484,13 +579,14 @@ grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view,
if (set_graphics_mode () != GRUB_ERR_NONE) if (set_graphics_mode () != GRUB_ERR_NONE)
return 0; /* Failure. */ return 0; /* Failure. */
init_terminal (view); grub_gfxmenu_view_draw (view);
return 1; /* Ok. */ return 1; /* Ok. */
} }
void void
grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view __attribute__((unused))) grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view)
{ {
draw_terminal_box (); draw_terminal_box (view);
grub_cmdline_run (1); grub_cmdline_run (1);
grub_gfxmenu_view_draw (view);
} }

View file

@ -54,7 +54,15 @@ int grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view,
void grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view); void grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view);
void
grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view);
void
grub_gfxmenu_redraw_timeout (grub_gfxmenu_view_t view);
void
grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
const grub_video_rect_t *region);
/* Implementation details -- this should not be used outside of the /* Implementation details -- this should not be used outside of the
view itself. */ view itself. */
@ -86,6 +94,12 @@ struct grub_gfxmenu_view
grub_gui_container_t canvas; grub_gui_container_t canvas;
grub_gfxmenu_model_t model; grub_gfxmenu_model_t model;
int last_seconds_remaining;
int double_repaint;
grub_video_rect_t progress_message_frame;
}; };
#endif /* ! GRUB_GFXMENU_VIEW_HEADER */ #endif /* ! GRUB_GFXMENU_VIEW_HEADER */

View file

@ -50,13 +50,14 @@ struct grub_gui_component_ops
void (*destroy) (void *self); void (*destroy) (void *self);
const char * (*get_id) (void *self); const char * (*get_id) (void *self);
int (*is_instance) (void *self, const char *type); int (*is_instance) (void *self, const char *type);
void (*paint) (void *self); void (*paint) (void *self, const grub_video_rect_t *bounds);
void (*set_parent) (void *self, grub_gui_container_t parent); void (*set_parent) (void *self, grub_gui_container_t parent);
grub_gui_container_t (*get_parent) (void *self); grub_gui_container_t (*get_parent) (void *self);
void (*set_bounds) (void *self, const grub_video_rect_t *bounds); void (*set_bounds) (void *self, const grub_video_rect_t *bounds);
void (*get_bounds) (void *self, grub_video_rect_t *bounds); void (*get_bounds) (void *self, grub_video_rect_t *bounds);
void (*get_preferred_size) (void *self, int *width, int *height); void (*get_preferred_size) (void *self, int *width, int *height);
grub_err_t (*set_property) (void *self, const char *name, const char *value); grub_err_t (*set_property) (void *self, const char *name, const char *value);
void (*repaint) (void *self, int second_pass);
}; };
struct grub_gui_container_ops struct grub_gui_container_ops
@ -162,4 +163,17 @@ grub_gui_map_color (grub_gui_color_t c)
return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha);
} }
static inline int
grub_video_have_common_points (const grub_video_rect_t *a,
const grub_video_rect_t *b)
{
if (!((a->x <= b->x && b->x <= a->x + a->width)
|| (b->x <= a->x && a->x <= b->x + b->width)))
return 0;
if (!((a->y <= b->y && b->y <= a->y + a->height)
|| (b->y <= a->y && a->y <= b->y + b->height)))
return 0;
return 1;
}
#endif /* ! GRUB_GUI_H */ #endif /* ! GRUB_GUI_H */