* grub-core/gfxmenu/gui_box.c: Updated to work with area status.

* grub-core/gfxmenu/gui_canvas.c: Likewise.
        * grub-core/gfxmenu/view.c: Likewise.
        * grub-core/video/fb/video_fb.c: Introduce new functions:
        grub_video_set_area_status, grub_video_get_area_status,
        grub_video_set_region, grub_video_get_region.
        * grub-core/video/bochs.c: Likewise.
        * grub-core/video/capture.c: Likewise.
        * grub-core/video/video.c: Likewise.
        * grub-core/video/cirrus.c: Likewise.
        * grub-core/video/efi_gop.c: Likewise.
        * grub-core/video/efi_uga.c: Likewise.
        * grub-core/video/emu/sdl.c: Likewise.
        * grub-core/video/radeon_fuloong2e.c: Likewise.
        * grub-core/video/sis315pro.c: Likewise.
        * grub-core/video/sm712.c: Likewise.
        * grub-core/video/i386/pc/vbe.c: Likewise.
        * grub-core/video/i386/pc/vga.c: Likewise.
        * grub-core/video/ieee1275.c: Likewise.
        * grub-core/video/i386/coreboot/cbfb.c: Likewise.
        * include/grub/video.h: Likewise.
        * include/grub/video_fb.h: Likewise.
        * include/grub/fbfill.h: Updated render_target structure.
        grub_video_rect_t viewport, region, area
        int area_offset_x, area_offset_y, area_enabled
        * include/grub/gui.h: New helper function
        grub_video_bounds_inside_region.
        * docs/grub-dev.texi: Added information about new functions.
This commit is contained in:
Vladimir Testov 2013-11-08 15:42:38 +04:00
parent c6b755df45
commit 4db2250000
24 changed files with 536 additions and 34 deletions

View file

@ -1,3 +1,34 @@
2013-11-08 Vladimir Testov <vladimir.testov@rosalab.ru>
* grub-core/gfxmenu/gui_box.c: Updated to work with area status.
* grub-core/gfxmenu/gui_canvas.c: Likewise.
* grub-core/gfxmenu/view.c: Likewise.
* grub-core/video/fb/video_fb.c: Introduce new functions:
grub_video_set_area_status, grub_video_get_area_status,
grub_video_set_region, grub_video_get_region.
* grub-core/video/bochs.c: Likewise.
* grub-core/video/capture.c: Likewise.
* grub-core/video/video.c: Likewise.
* grub-core/video/cirrus.c: Likewise.
* grub-core/video/efi_gop.c: Likewise.
* grub-core/video/efi_uga.c: Likewise.
* grub-core/video/emu/sdl.c: Likewise.
* grub-core/video/radeon_fuloong2e.c: Likewise.
* grub-core/video/sis315pro.c: Likewise.
* grub-core/video/sm712.c: Likewise.
* grub-core/video/i386/pc/vbe.c: Likewise.
* grub-core/video/i386/pc/vga.c: Likewise.
* grub-core/video/ieee1275.c: Likewise.
* grub-core/video/i386/coreboot/cbfb.c: Likewise.
* include/grub/video.h: Likewise.
* include/grub/video_fb.h: Likewise.
* include/grub/fbfill.h: Updated render_target structure.
grub_video_rect_t viewport, region, area
int area_offset_x, area_offset_y, area_enabled
* include/grub/gui.h: New helper function
grub_video_bounds_inside_region.
* docs/grub-dev.texi: Added information about new functions.
2013-11-08 Vladimir Serbinenko <phcoder@gmail.com> 2013-11-08 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/mm.c (grub_real_malloc): Use AND rather than MOD * grub-core/kern/mm.c (grub_real_malloc): Use AND rather than MOD

View file

@ -1113,6 +1113,47 @@ struct grub_video_palette_data
Used to query indexed color palettes. If mode is RGB mode, colors will be copied from emulated palette data. In Indexed Color modes, palettes will be read from hardware. Color values will be converted to suit structure format. @code{start} will tell what hardware color index (or emulated color index) will be used as a source for first indice of @code{palette_data}, after that both hardware color index and @code{palette_data} index will be incremented until @code{count} number of colors have been read. Used to query indexed color palettes. If mode is RGB mode, colors will be copied from emulated palette data. In Indexed Color modes, palettes will be read from hardware. Color values will be converted to suit structure format. @code{start} will tell what hardware color index (or emulated color index) will be used as a source for first indice of @code{palette_data}, after that both hardware color index and @code{palette_data} index will be incremented until @code{count} number of colors have been read.
@end itemize @end itemize
@subsection grub_video_set_area_status
@itemize
@item Prototype:
@example
grub_err_t
grub_video_set_area_status (grub_video_area_status_t area_status);
@end example
@example
enum grub_video_area_status_t
@{
GRUB_VIDEO_AREA_DISABLED,
GRUB_VIDEO_AREA_ENABLED
@};
@end example
@item Description:
Used to set area drawing mode for redrawing the specified region. Draw commands
are performed in the intersection of the viewport and the region called area.
Coordinates remain related to the viewport. If draw commands try to draw over
the area, they are clipped.
Set status to DISABLED if you need to draw everything.
Set status to ENABLED and region to the desired rectangle to redraw everything
inside the region leaving everything else intact.
Should be used for redrawing of active elements.
@end itemize
@subsection grub_video_get_area_status
@itemize
@item Prototype:
@example
grub_err_r
grub_video_get_area_status (grub_video_area_status_t *area_status);
@end example
@item Description:
Used to query the area status.
@end itemize
@subsection grub_video_set_viewport @subsection grub_video_set_viewport
@itemize @itemize
@item Prototype: @item Prototype:
@ -1139,6 +1180,37 @@ grub_video_get_viewport (unsigned int *x, unsigned int *y, unsigned int *width,
Used to query current viewport dimensions. Software developer can use this to choose best way to render contents of the viewport. Used to query current viewport dimensions. Software developer can use this to choose best way to render contents of the viewport.
@end itemize @end itemize
@subsection grub_video_set_region
@itemize
@item Prototype:
@example
grub_err_t
grub_video_set_region (unsigned int x, unsigned int y, unsigned int width, unsigned int height);
@end example
@item Description:
Used to specify the region of the screen which should be redrawn. Use absolute
values. When the region is set and area status is ENABLE all draw commands will
be performed inside the interseption of region and viewport named area.
If draw commands try to draw over viewport, they are clipped. If developer
requests larger than possible region, width and height will be clamped to fit
screen. Should be used for redrawing of active elements.
@end itemize
@subsection grub_video_get_region
@itemize
@item Prototype:
@example
grub_err_t
grub_video_get_region (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height);
@end example
@item Description:
Used to query current region dimensions.
@end itemize
@subsection grub_video_map_color @subsection grub_video_map_color
@itemize @itemize
@item Prototype: @item Prototype:

View file

@ -234,14 +234,30 @@ static void
box_paint (void *vself, const grub_video_rect_t *region) 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;
grub_video_rect_t vpsave; grub_video_rect_t vpsave;
grub_video_area_status_t box_area_status;
grub_video_get_area_status (&box_area_status);
grub_gui_set_viewport (&self->bounds, &vpsave); grub_gui_set_viewport (&self->bounds, &vpsave);
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;
grub_video_rect_t r;
comp->ops->get_bounds(comp, &r);
if (!grub_video_have_common_points (region, &r))
continue;
/* Paint the child. */
if (box_area_status == GRUB_VIDEO_AREA_ENABLED
&& grub_video_bounds_inside_region (&r, region))
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
comp->ops->paint (comp, region); comp->ops->paint (comp, region);
if (box_area_status == GRUB_VIDEO_AREA_ENABLED)
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
} }
grub_gui_restore_viewport (&vpsave); grub_gui_restore_viewport (&vpsave);
} }

View file

@ -80,9 +80,13 @@ static void
canvas_paint (void *vself, const grub_video_rect_t *region) 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;
grub_video_rect_t vpsave; grub_video_rect_t vpsave;
grub_video_area_status_t canvas_area_status;
grub_video_get_area_status (&canvas_area_status);
grub_gui_set_viewport (&self->bounds, &vpsave); grub_gui_set_viewport (&self->bounds, &vpsave);
for (cur = self->components.next; cur; cur = cur->next) for (cur = self->components.next; cur; cur = cur->next)
{ {
@ -135,9 +139,16 @@ canvas_paint (void *vself, const grub_video_rect_t *region)
r.height = h; r.height = h;
comp->ops->set_bounds (comp, &r); comp->ops->set_bounds (comp, &r);
if (!grub_video_have_common_points (region, &r))
continue;
/* Paint the child. */ /* Paint the child. */
if (grub_video_have_common_points (region, &r)) if (canvas_area_status == GRUB_VIDEO_AREA_ENABLED
&& grub_video_bounds_inside_region (&r, region))
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
comp->ops->paint (comp, region); comp->ops->paint (comp, region);
if (canvas_area_status == GRUB_VIDEO_AREA_ENABLED)
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
} }
grub_gui_restore_viewport (&vpsave); grub_gui_restore_viewport (&vpsave);
} }

View file

@ -213,6 +213,7 @@ redraw_timeouts (struct grub_gfxmenu_view *view)
{ {
grub_video_rect_t bounds; grub_video_rect_t bounds;
cur->self->ops->get_bounds (cur->self, &bounds); cur->self->ops->get_bounds (cur->self, &bounds);
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
grub_gfxmenu_view_redraw (view, &bounds); grub_gfxmenu_view_redraw (view, &bounds);
} }
} }
@ -321,6 +322,11 @@ grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
grub_gfxterm_schedule_repaint (); grub_gfxterm_schedule_repaint ();
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
grub_video_area_status_t area_status;
grub_video_get_area_status (&area_status);
if (area_status == GRUB_VIDEO_AREA_ENABLED)
grub_video_set_region (region->x, region->y,
region->width, region->height);
redraw_background (view, region); redraw_background (view, region);
if (view->canvas) if (view->canvas)
@ -328,6 +334,9 @@ grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
draw_title (view); draw_title (view);
if (grub_video_have_common_points (&view->progress_message_frame, region)) if (grub_video_have_common_points (&view->progress_message_frame, region))
draw_message (view); draw_message (view);
if (area_status == GRUB_VIDEO_AREA_ENABLED)
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
} }
void void
@ -350,10 +359,15 @@ grub_gfxmenu_view_draw (grub_gfxmenu_view_t view)
refresh_menu_components (view); refresh_menu_components (view);
update_menu_components (view); update_menu_components (view);
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
grub_gfxmenu_view_redraw (view, &view->screen); grub_gfxmenu_view_redraw (view, &view->screen);
grub_video_swap_buffers (); grub_video_swap_buffers ();
if (view->double_repaint) if (view->double_repaint)
{
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
grub_gfxmenu_view_redraw (view, &view->screen); grub_gfxmenu_view_redraw (view, &view->screen);
}
} }
static void static void
@ -367,6 +381,7 @@ redraw_menu_visit (grub_gui_component_t component,
grub_video_rect_t bounds; grub_video_rect_t bounds;
component->ops->get_bounds (component, &bounds); component->ops->get_bounds (component, &bounds);
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
grub_gfxmenu_view_redraw (view, &bounds); grub_gfxmenu_view_redraw (view, &bounds);
} }
} }
@ -404,6 +419,8 @@ grub_gfxmenu_draw_terminal_box (void)
if (!term_box) if (!term_box)
return; return;
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
term_box->set_content_size (term_box, term_view->terminal_rect.width, term_box->set_content_size (term_box, term_view->terminal_rect.width,
term_view->terminal_rect.height); term_view->terminal_rect.height);

View file

@ -401,6 +401,10 @@ static struct grub_video_adapter grub_video_bochs_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -51,6 +51,10 @@ static struct grub_video_adapter grub_video_capture_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -480,6 +480,10 @@ static struct grub_video_adapter grub_video_cirrus_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -586,6 +586,10 @@ static struct grub_video_adapter grub_video_gop_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -327,6 +327,10 @@ static struct grub_video_adapter grub_video_uga_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -220,6 +220,10 @@ static struct grub_video_adapter grub_video_sdl_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -399,12 +399,67 @@ grub_video_fb_set_palette (unsigned int start, unsigned int count,
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static grub_err_t
grub_video_fb_set_area (void)
{
unsigned int viewport_x1 = framebuffer.render_target->viewport.x;
unsigned int viewport_y1 = framebuffer.render_target->viewport.y;
unsigned int viewport_width = framebuffer.render_target->viewport.width;
unsigned int viewport_height = framebuffer.render_target->viewport.height;
unsigned int viewport_x2 = viewport_x1 + viewport_width;
unsigned int viewport_y2 = viewport_y1 + viewport_height;
unsigned int region_x1 = framebuffer.render_target->region.x;
unsigned int region_y1 = framebuffer.render_target->region.y;
unsigned int region_width = framebuffer.render_target->region.width;
unsigned int region_height = framebuffer.render_target->region.height;
unsigned int region_x2 = region_x1 + region_width;
unsigned int region_y2 = region_y1 + region_height;
unsigned int max_x1 = grub_max (viewport_x1, region_x1);
unsigned int min_x2 = grub_min (viewport_x2, region_x2);
unsigned int max_y1 = grub_max (viewport_y1, region_y1);
unsigned int min_y2 = grub_min (viewport_y2, region_y2);
/* Viewport and region do not intersect. */
if (viewport_width == 0 || viewport_height == 0 || region_width == 0
|| region_height == 0 || max_x1 >= min_x2 || max_y1 >= min_y2)
{
framebuffer.render_target->area.x = 0;
framebuffer.render_target->area.y = 0;
framebuffer.render_target->area.width = 0;
framebuffer.render_target->area.height = 0;
framebuffer.render_target->area_offset_x = 0;
framebuffer.render_target->area_offset_y = 0;
return GRUB_ERR_NONE;
}
/* There is non-zero intersection. */
framebuffer.render_target->area.x = max_x1;
framebuffer.render_target->area.y = max_y1;
framebuffer.render_target->area.width = min_x2 - max_x1;
framebuffer.render_target->area.height = min_y2 - max_y1;
if (region_x1 > viewport_x1)
framebuffer.render_target->area_offset_x = (int)region_x1
- (int)viewport_x1;
else
framebuffer.render_target->area_offset_x = 0;
if (region_y1 > viewport_y1)
framebuffer.render_target->area_offset_y = (int)region_y1
- (int)viewport_y1;
else
framebuffer.render_target->area_offset_y = 0;
return GRUB_ERR_NONE;
}
grub_err_t grub_err_t
grub_video_fb_set_viewport (unsigned int x, unsigned int y, grub_video_fb_set_viewport (unsigned int x, unsigned int y,
unsigned int width, unsigned int height) unsigned int width, unsigned int height)
{ {
/* Make sure viewport is withing screen dimensions. If viewport was set /* Make sure viewport is within screen dimensions. If viewport was set
to be out of the region, mark its size as zero. */ to be out of the screen, mark its size as zero. */
if (x > framebuffer.render_target->mode_info.width) if (x > framebuffer.render_target->mode_info.width)
{ {
x = 0; x = 0;
@ -428,6 +483,10 @@ grub_video_fb_set_viewport (unsigned int x, unsigned int y,
framebuffer.render_target->viewport.width = width; framebuffer.render_target->viewport.width = width;
framebuffer.render_target->viewport.height = height; framebuffer.render_target->viewport.height = height;
/* Count drawing area only if needed. */
if (framebuffer.render_target->area_enabled)
grub_video_fb_set_area ();
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -443,6 +502,78 @@ grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
grub_err_t
grub_video_fb_set_region (unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
/* Make sure region is within screen dimensions. If region was set
to be out of the screen, mark its size as zero. */
if (x > framebuffer.render_target->mode_info.width)
{
x = 0;
width = 0;
}
if (y > framebuffer.render_target->mode_info.height)
{
y = 0;
height = 0;
}
if (x + width > framebuffer.render_target->mode_info.width)
width = framebuffer.render_target->mode_info.width - x;
if (y + height > framebuffer.render_target->mode_info.height)
height = framebuffer.render_target->mode_info.height - y;
framebuffer.render_target->region.x = x;
framebuffer.render_target->region.y = y;
framebuffer.render_target->region.width = width;
framebuffer.render_target->region.height = height;
/* If we have called set_region then area is needed. */
grub_video_fb_set_area ();
return GRUB_ERR_NONE;
}
grub_err_t
grub_video_fb_get_region (unsigned int *x, unsigned int *y,
unsigned int *width, unsigned int *height)
{
if (x) *x = framebuffer.render_target->region.x;
if (y) *y = framebuffer.render_target->region.y;
if (width) *width = framebuffer.render_target->region.width;
if (height) *height = framebuffer.render_target->region.height;
return GRUB_ERR_NONE;
}
grub_err_t
grub_video_fb_set_area_status (grub_video_area_status_t area_status)
{
if (area_status == GRUB_VIDEO_AREA_ENABLED)
framebuffer.render_target->area_enabled = 1;
else
framebuffer.render_target->area_enabled = 0;
return GRUB_ERR_NONE;
}
grub_err_t
grub_video_fb_get_area_status (grub_video_area_status_t *area_status)
{
if (!area_status)
return GRUB_ERR_NONE;
if (framebuffer.render_target->area_enabled)
*area_status = GRUB_VIDEO_AREA_ENABLED;
else
*area_status = GRUB_VIDEO_AREA_DISABLED;
return GRUB_ERR_NONE;
}
/* Maps color name to target optimized color format. */ /* Maps color name to target optimized color format. */
grub_video_color_t grub_video_color_t
grub_video_fb_map_color (grub_uint32_t color_name) grub_video_fb_map_color (grub_uint32_t color_name)
@ -714,14 +845,36 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
unsigned int width, unsigned int height) unsigned int width, unsigned int height)
{ {
struct grub_video_fbblit_info target; struct grub_video_fbblit_info target;
unsigned int area_x;
unsigned int area_y;
unsigned int area_width;
unsigned int area_height;
if (framebuffer.render_target->area_enabled)
{
area_x = framebuffer.render_target->area.x;
area_y = framebuffer.render_target->area.y;
area_width = framebuffer.render_target->area.width;
area_height = framebuffer.render_target->area.height;
x -= framebuffer.render_target->area_offset_x;
y -= framebuffer.render_target->area_offset_y;
}
else
{
area_x = framebuffer.render_target->viewport.x;
area_y = framebuffer.render_target->viewport.y;
area_width = framebuffer.render_target->viewport.width;
area_height = framebuffer.render_target->viewport.height;
}
/* Make sure there is something to do. */ /* Make sure there is something to do. */
if ((x >= (int)framebuffer.render_target->viewport.width) || (x + (int)width < 0)) if ((area_width == 0) || (area_height == 0))
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
if ((y >= (int)framebuffer.render_target->viewport.height) || (y + (int)height < 0)) if ((x >= (int)area_width) || (x + (int)width < 0))
return GRUB_ERR_NONE;
if ((y >= (int)area_height) || (y + (int)height < 0))
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
/* Do not allow drawing out of viewport. */ /* Do not allow drawing out of area. */
if (x < 0) if (x < 0)
{ {
width += x; width += x;
@ -733,14 +886,14 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
y = 0; y = 0;
} }
if ((x + width) > framebuffer.render_target->viewport.width) if ((x + width) > area_width)
width = framebuffer.render_target->viewport.width - x; width = area_width - x;
if ((y + height) > framebuffer.render_target->viewport.height) if ((y + height) > area_height)
height = framebuffer.render_target->viewport.height - y; height = area_height - y;
/* Add viewport offset. */ /* Add area offset. */
x += framebuffer.render_target->viewport.x; x += area_x;
y += framebuffer.render_target->viewport.y; y += area_y;
dirty (y, height); dirty (y, height);
@ -760,13 +913,33 @@ grub_video_fb_blit_source (struct grub_video_fbblit_info *source,
unsigned int width, unsigned int height) unsigned int width, unsigned int height)
{ {
struct grub_video_fbblit_info target; struct grub_video_fbblit_info target;
unsigned int area_x;
unsigned int area_y;
unsigned int area_width;
unsigned int area_height;
if (framebuffer.render_target->area_enabled)
{
area_x = framebuffer.render_target->area.x;
area_y = framebuffer.render_target->area.y;
area_width = framebuffer.render_target->area.width;
area_height = framebuffer.render_target->area.height;
x -= framebuffer.render_target->area_offset_x;
y -= framebuffer.render_target->area_offset_y;
}
else
{
area_x = framebuffer.render_target->viewport.x;
area_y = framebuffer.render_target->viewport.y;
area_width = framebuffer.render_target->viewport.width;
area_height = framebuffer.render_target->viewport.height;
}
/* Make sure there is something to do. */ /* Make sure there is something to do. */
if ((width == 0) || (height == 0)) if ((area_width == 0) || (area_height == 0) || (width == 0) || (height == 0))
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
if ((x >= (int)framebuffer.render_target->viewport.width) || (x + (int)width < 0)) if ((x >= (int)area_width) || (x + (int)width < 0))
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
if ((y >= (int)framebuffer.render_target->viewport.height) || (y + (int)height < 0)) if ((y >= (int)area_height) || (y + (int)height < 0))
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
if ((x + (int)source->mode_info->width) < 0) if ((x + (int)source->mode_info->width) < 0)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@ -808,11 +981,11 @@ grub_video_fb_blit_source (struct grub_video_fbblit_info *source,
y = 0; y = 0;
} }
/* Do not allow drawing out of viewport. */ /* Do not allow drawing out of area. */
if ((x + width) > framebuffer.render_target->viewport.width) if ((x + width) > area_width)
width = framebuffer.render_target->viewport.width - x; width = area_width - x;
if ((y + height) > framebuffer.render_target->viewport.height) if ((y + height) > area_height)
height = framebuffer.render_target->viewport.height - y; height = area_height - y;
if ((offset_x + width) > source->mode_info->width) if ((offset_x + width) > source->mode_info->width)
width = source->mode_info->width - offset_x; width = source->mode_info->width - offset_x;
@ -827,8 +1000,8 @@ grub_video_fb_blit_source (struct grub_video_fbblit_info *source,
height = source->mode_info->height; height = source->mode_info->height;
/* Add viewport offset. */ /* Add viewport offset. */
x += framebuffer.render_target->viewport.x; x += area_x;
y += framebuffer.render_target->viewport.y; y += area_y;
/* Use fbblit_info to encapsulate rendering. */ /* Use fbblit_info to encapsulate rendering. */
target.mode_info = &framebuffer.render_target->mode_info; target.mode_info = &framebuffer.render_target->mode_info;
@ -1058,12 +1231,25 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
/* Mark render target as allocated. */ /* Mark render target as allocated. */
target->is_allocated = 1; target->is_allocated = 1;
/* Maximize viewport. */ /* Maximize viewport, region and area. */
target->viewport.x = 0; target->viewport.x = 0;
target->viewport.y = 0; target->viewport.y = 0;
target->viewport.width = width; target->viewport.width = width;
target->viewport.height = height; target->viewport.height = height;
target->region.x = 0;
target->region.y = 0;
target->region.width = width;
target->region.height = height;
target->area_enabled = 0;
target->area.x = 0;
target->area.y = 0;
target->area.width = width;
target->area.height = height;
target->area_offset_x = 0;
target->area_offset_y = 0;
/* Setup render target format. */ /* Setup render target format. */
target->mode_info.width = width; target->mode_info.width = width;
target->mode_info.height = height; target->mode_info.height = height;
@ -1150,12 +1336,25 @@ grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_targ
grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info)); grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info));
/* Reset viewport to match new mode. */ /* Reset viewport, region and area to match new mode. */
target->viewport.x = 0; target->viewport.x = 0;
target->viewport.y = 0; target->viewport.y = 0;
target->viewport.width = mode_info->width; target->viewport.width = mode_info->width;
target->viewport.height = mode_info->height; target->viewport.height = mode_info->height;
target->region.x = 0;
target->region.y = 0;
target->region.width = mode_info->width;
target->region.height = mode_info->height;
target->area_enabled = 0;
target->area.x = 0;
target->area.y = 0;
target->area.width = mode_info->width;
target->area.height = mode_info->height;
target->area_offset_x = 0;
target->area_offset_y = 0;
/* Clear render target with black and maximum transparency. */ /* Clear render target with black and maximum transparency. */
for (y = 0; y < mode_info->height; y++) for (y = 0; y < mode_info->height; y++)
grub_memset (target->data + mode_info->pitch * y, 0, grub_memset (target->data + mode_info->pitch * y, 0,

View file

@ -138,6 +138,10 @@ static struct grub_video_adapter grub_video_cbfb_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -1214,6 +1214,10 @@ static struct grub_video_adapter grub_video_vbe_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -372,6 +372,10 @@ static struct grub_video_adapter grub_video_vga_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -328,6 +328,10 @@ static struct grub_video_adapter grub_video_ieee1275_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -207,6 +207,10 @@ static struct grub_video_adapter grub_video_radeon_fuloong2e_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -420,6 +420,10 @@ static struct grub_video_adapter grub_video_sis315pro_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -779,6 +779,10 @@ static struct grub_video_adapter grub_video_sm712_adapter =
.get_palette = grub_video_fb_get_palette, .get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport, .set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport, .get_viewport = grub_video_fb_get_viewport,
.set_region = grub_video_fb_set_region,
.get_region = grub_video_fb_get_region,
.set_area_status = grub_video_fb_set_area_status,
.get_area_status = grub_video_fb_get_area_status,
.map_color = grub_video_fb_map_color, .map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb, .map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba, .map_rgba = grub_video_fb_map_rgba,

View file

@ -225,6 +225,48 @@ grub_video_get_viewport (unsigned int *x, unsigned int *y,
return grub_video_adapter_active->get_viewport (x, y, width, height); return grub_video_adapter_active->get_viewport (x, y, width, height);
} }
/* Set region dimensions. */
grub_err_t
grub_video_set_region (unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
if (! grub_video_adapter_active)
return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
return grub_video_adapter_active->set_region (x, y, width, height);
}
/* Get region dimensions. */
grub_err_t
grub_video_get_region (unsigned int *x, unsigned int *y,
unsigned int *width, unsigned int *height)
{
if (! grub_video_adapter_active)
return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
return grub_video_adapter_active->get_region (x, y, width, height);
}
/* Set status of the intersection of the viewport and the region. */
grub_err_t
grub_video_set_area_status (grub_video_area_status_t area_status)
{
if (! grub_video_adapter_active)
return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
return grub_video_adapter_active->set_area_status (area_status);
}
/* Get status of the intersection of the viewport and the region. */
grub_err_t
grub_video_get_area_status (grub_video_area_status_t *area_status)
{
if (! grub_video_adapter_active)
return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
return grub_video_adapter_active->get_area_status (area_status);
}
/* Map color name to adapter specific color. */ /* Map color name to adapter specific color. */
grub_video_color_t grub_video_color_t
grub_video_map_color (grub_uint32_t color_name) grub_video_map_color (grub_uint32_t color_name)

View file

@ -30,13 +30,17 @@ struct grub_video_fbrender_target
mode_type has been re-adjusted to requested render target settings. */ mode_type has been re-adjusted to requested render target settings. */
struct grub_video_mode_info mode_info; struct grub_video_mode_info mode_info;
struct /* We should not draw outside of viewport. */
{ grub_video_rect_t viewport;
unsigned int x; /* Set region to make a re-draw of a part of the screen. */
unsigned int y; grub_video_rect_t region;
unsigned int width; /* Should be set to 0 if the viewport is inside of the region. */
unsigned int height; int area_enabled;
} viewport; /* Internal structure - intersection of the viewport and the region. */
grub_video_rect_t area;
/* Internal values - offsets from the left top point of the viewport. */
int area_offset_x;
int area_offset_y;
/* Indicates whether the data has been allocated by us and must be freed /* Indicates whether the data has been allocated by us and must be freed
when render target is destroyed. */ when render target is destroyed. */

View file

@ -248,4 +248,15 @@ grub_video_have_common_points (const grub_video_rect_t *a,
return 1; return 1;
} }
static inline int
grub_video_bounds_inside_region (const grub_video_rect_t *b,
const grub_video_rect_t *r)
{
if (r->x > b->x || r->x + r->width < b->x + b->width)
return 0;
if (r->y > b->y || r->y + r->height < b->y + b->height)
return 0;
return 1;
}
#endif /* ! GRUB_GUI_H */ #endif /* ! GRUB_GUI_H */

View file

@ -301,6 +301,11 @@ typedef enum grub_video_adapter_prio
GRUB_VIDEO_ADAPTER_PRIO_NATIVE = 100 GRUB_VIDEO_ADAPTER_PRIO_NATIVE = 100
} grub_video_adapter_prio_t; } grub_video_adapter_prio_t;
typedef enum grub_video_area_status
{
GRUB_VIDEO_AREA_DISABLED,
GRUB_VIDEO_AREA_ENABLED
} grub_video_area_status_t;
struct grub_video_adapter struct grub_video_adapter
{ {
@ -341,6 +346,16 @@ struct grub_video_adapter
grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y, grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y,
unsigned int *width, unsigned int *height); unsigned int *width, unsigned int *height);
grub_err_t (*set_region) (unsigned int x, unsigned int y,
unsigned int width, unsigned int height);
grub_err_t (*get_region) (unsigned int *x, unsigned int *y,
unsigned int *width, unsigned int *height);
grub_err_t (*set_area_status) (grub_video_area_status_t area_status);
grub_err_t (*get_area_status) (grub_video_area_status_t *area_status);
grub_video_color_t (*map_color) (grub_uint32_t color_name); grub_video_color_t (*map_color) (grub_uint32_t color_name);
grub_video_color_t (*map_rgb) (grub_uint8_t red, grub_uint8_t green, grub_video_color_t (*map_rgb) (grub_uint8_t red, grub_uint8_t green,
@ -447,6 +462,22 @@ grub_err_t EXPORT_FUNC (grub_video_get_viewport) (unsigned int *x,
unsigned int *width, unsigned int *width,
unsigned int *height); unsigned int *height);
grub_err_t EXPORT_FUNC (grub_video_set_region) (unsigned int x,
unsigned int y,
unsigned int width,
unsigned int height);
grub_err_t EXPORT_FUNC (grub_video_get_region) (unsigned int *x,
unsigned int *y,
unsigned int *width,
unsigned int *height);
grub_err_t EXPORT_FUNC (grub_video_set_area_status)
(grub_video_area_status_t area_status);
grub_err_t EXPORT_FUNC (grub_video_get_area_status)
(grub_video_area_status_t *area_status);
grub_video_color_t EXPORT_FUNC (grub_video_map_color) (grub_uint32_t color_name); grub_video_color_t EXPORT_FUNC (grub_video_map_color) (grub_uint32_t color_name);
grub_video_color_t EXPORT_FUNC (grub_video_map_rgb) (grub_uint8_t red, grub_video_color_t EXPORT_FUNC (grub_video_map_rgb) (grub_uint8_t red,

View file

@ -58,6 +58,22 @@ EXPORT_FUNC(grub_video_fb_get_viewport) (unsigned int *x, unsigned int *y,
unsigned int *width, unsigned int *width,
unsigned int *height); unsigned int *height);
grub_err_t
EXPORT_FUNC(grub_video_fb_set_region) (unsigned int x, unsigned int y,
unsigned int width, unsigned int height);
grub_err_t
EXPORT_FUNC(grub_video_fb_get_region) (unsigned int *x, unsigned int *y,
unsigned int *width,
unsigned int *height);
grub_err_t
EXPORT_FUNC(grub_video_fb_set_area_status)
(grub_video_area_status_t area_status);
grub_err_t
EXPORT_FUNC(grub_video_fb_get_area_status)
(grub_video_area_status_t *area_status);
grub_video_color_t grub_video_color_t
EXPORT_FUNC(grub_video_fb_map_color) (grub_uint32_t color_name); EXPORT_FUNC(grub_video_fb_map_color) (grub_uint32_t color_name);