]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/gfxmenu/gui_box.c: Updated to work with area status.
authorVladimir Testov <vladimir.testov@rosalab.ru>
Fri, 8 Nov 2013 11:42:38 +0000 (15:42 +0400)
committerVladimir Testov <vladimir.testov@rosalab.ru>
Fri, 8 Nov 2013 11:42:38 +0000 (15:42 +0400)
        * 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.

24 files changed:
ChangeLog
docs/grub-dev.texi
grub-core/gfxmenu/gui_box.c
grub-core/gfxmenu/gui_canvas.c
grub-core/gfxmenu/view.c
grub-core/video/bochs.c
grub-core/video/capture.c
grub-core/video/cirrus.c
grub-core/video/efi_gop.c
grub-core/video/efi_uga.c
grub-core/video/emu/sdl.c
grub-core/video/fb/video_fb.c
grub-core/video/i386/coreboot/cbfb.c
grub-core/video/i386/pc/vbe.c
grub-core/video/i386/pc/vga.c
grub-core/video/ieee1275.c
grub-core/video/radeon_fuloong2e.c
grub-core/video/sis315pro.c
grub-core/video/sm712.c
grub-core/video/video.c
include/grub/fbfill.h
include/grub/gui.h
include/grub/video.h
include/grub/video_fb.h

index 12228372625f8ad31d7d62926947698e6d1d2011..f8a01488091cc8bcf5592a242f29fd9c9acc2009 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * grub-core/kern/mm.c (grub_real_malloc): Use AND rather than MOD
index 9499f8bc49bd7aa5ba9ef1baf82277687f15100e..6caec789699eeafd9822d22a46fda2b418781e6e 100644 (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.
 @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
 @itemize
 @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.
 @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
 @itemize
 @item Prototype:
index 38b15f96d263df062e8421319e9f854161322214..37bab3fbb184c13a645754b11d674c193a8f4dca 100644 (file)
@@ -234,14 +234,30 @@ static void
 box_paint (void *vself, const grub_video_rect_t *region)
 {
   grub_gui_box_t self = vself;
+
   struct component_node *cur;
   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);
   for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
     {
       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);
+      if (box_area_status == GRUB_VIDEO_AREA_ENABLED)
+        grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
     }
   grub_gui_restore_viewport (&vpsave);
 }
index b3919c2d3ea460e6803fbd28ef468cd81b36e693..a054912422761ed937d370f68b0ebccf83a749ab 100644 (file)
@@ -80,9 +80,13 @@ static void
 canvas_paint (void *vself, const grub_video_rect_t *region)
 {
   grub_gui_canvas_t self = vself;
+
   struct component_node *cur;
   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);
   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;
       comp->ops->set_bounds (comp, &r);
 
+      if (!grub_video_have_common_points (region, &r))
+        continue;
+
       /* Paint the child.  */
-      if (grub_video_have_common_points (region, &r))
-       comp->ops->paint (comp, region);
+      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);
+      if (canvas_area_status == GRUB_VIDEO_AREA_ENABLED)
+        grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
     }
   grub_gui_restore_viewport (&vpsave);
 }
index ed58cdc6d15fc509c27c9d95ad4f3562f6d671d9..ad5e82b81c68d3a8965e3c2efe80c91f5bc97e01 100644 (file)
@@ -213,6 +213,7 @@ redraw_timeouts (struct grub_gfxmenu_view *view)
     {
       grub_video_rect_t bounds;
       cur->self->ops->get_bounds (cur->self, &bounds);
+      grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
       grub_gfxmenu_view_redraw (view, &bounds);
     }
 }
@@ -321,6 +322,11 @@ grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
     grub_gfxterm_schedule_repaint ();
 
   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);
   if (view->canvas)
@@ -328,6 +334,9 @@ grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
   draw_title (view);
   if (grub_video_have_common_points (&view->progress_message_frame, region))
     draw_message (view);
+
+  if (area_status == GRUB_VIDEO_AREA_ENABLED)
+    grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
 }
 
 void
@@ -350,10 +359,15 @@ grub_gfxmenu_view_draw (grub_gfxmenu_view_t view)
   refresh_menu_components (view);
   update_menu_components (view);
 
+  grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
   grub_gfxmenu_view_redraw (view, &view->screen);
   grub_video_swap_buffers ();
   if (view->double_repaint)
-    grub_gfxmenu_view_redraw (view, &view->screen);
+    {
+      grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
+      grub_gfxmenu_view_redraw (view, &view->screen);
+    }
+
 }
 
 static void
@@ -367,6 +381,7 @@ redraw_menu_visit (grub_gui_component_t component,
       grub_video_rect_t bounds;
 
       component->ops->get_bounds (component, &bounds);
+      grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
       grub_gfxmenu_view_redraw (view, &bounds);
     }
 }
@@ -404,6 +419,8 @@ grub_gfxmenu_draw_terminal_box (void)
   if (!term_box)
     return;
 
+  grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
+
   term_box->set_content_size (term_box, term_view->terminal_rect.width,
                              term_view->terminal_rect.height);
   
index 287ae0ff346955aba206187e2acdba0ea60583d0..4b8c205fbad0439e13af15af67cc8196e1051369 100644 (file)
@@ -401,6 +401,10 @@ static struct grub_video_adapter grub_video_bochs_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index bae6401ab214e49fa11755701ca373209de3f2e0..67c8edde824d206d947d0e9e264ef4186d83e1a6 100644 (file)
@@ -51,6 +51,10 @@ static struct grub_video_adapter grub_video_capture_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 00e6516ac4152679fa86288f6e53b9dcb219b7db..41baae4904afdf77186e45345f4efc80d963df25 100644 (file)
@@ -480,6 +480,10 @@ static struct grub_video_adapter grub_video_cirrus_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 42856440067c8a33399c5ed5730e8676f3921d97..7f9d1c2dfa192cc11a9574faa6e0b751a54b0df4 100644 (file)
@@ -586,6 +586,10 @@ static struct grub_video_adapter grub_video_gop_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 159df8e6117023cac1da0050f9ea871d5b088f04..464ede874daff480fb4199927cb30d48f0558e8b 100644 (file)
@@ -327,6 +327,10 @@ static struct grub_video_adapter grub_video_uga_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 6fd01be396bc8457d990af157dd7b6173d3f28d9..a2f639f66de5076dce83edddfb2d0b44f80edc9c 100644 (file)
@@ -220,6 +220,10 @@ static struct grub_video_adapter grub_video_sdl_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 6401e8a77dc5813e1be1701d38c51bf64c45471a..722bb3bb436bf9be4f485c71816cd08adb4dee09 100644 (file)
@@ -399,12 +399,67 @@ grub_video_fb_set_palette (unsigned int start, unsigned int count,
   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_video_fb_set_viewport (unsigned int x, unsigned int y,
                            unsigned int width, unsigned int height)
 {
-  /* Make sure viewport is withing screen dimensions.  If viewport was set
-     to be out of the region, mark its size as zero.  */
+  /* Make sure viewport is within screen dimensions.  If viewport was set
+     to be out of the screen, mark its size as zero.  */
   if (x > framebuffer.render_target->mode_info.width)
     {
       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.height = height;
 
+  /* Count drawing area only if needed. */
+  if (framebuffer.render_target->area_enabled)
+    grub_video_fb_set_area ();
+
   return GRUB_ERR_NONE;
 }
 
@@ -443,6 +502,78 @@ grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
   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.  */
 grub_video_color_t
 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)
 {
   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.  */
-  if ((x >= (int)framebuffer.render_target->viewport.width) || (x + (int)width < 0))
+  if ((area_width == 0) || (area_height == 0))
+    return GRUB_ERR_NONE;
+  if ((x >= (int)area_width) || (x + (int)width < 0))
     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;
 
-  /* Do not allow drawing out of viewport.  */
+  /* Do not allow drawing out of area.  */
   if (x < 0)
     {
       width += x;
@@ -733,14 +886,14 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
       y = 0;
     }
 
-  if ((x + width) > framebuffer.render_target->viewport.width)
-    width = framebuffer.render_target->viewport.width - x;
-  if ((y + height) > framebuffer.render_target->viewport.height)
-    height = framebuffer.render_target->viewport.height - y;
+  if ((x + width) > area_width)
+    width = area_width - x;
+  if ((y + height) > area_height)
+    height = area_height - y;
 
-  /* Add viewport offset.  */
-  x += framebuffer.render_target->viewport.x;
-  y += framebuffer.render_target->viewport.y;
+  /* Add area offset.  */
+  x += area_x;
+  y += area_y;
 
   dirty (y, height);
 
@@ -760,13 +913,33 @@ grub_video_fb_blit_source (struct grub_video_fbblit_info *source,
                            unsigned int width, unsigned int height)
 {
   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.  */
-  if ((width == 0) || (height == 0))
+  if ((area_width == 0) || (area_height == 0) || (width == 0) || (height == 0))
     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;
-  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;
   if ((x + (int)source->mode_info->width) < 0)
     return GRUB_ERR_NONE;
@@ -808,11 +981,11 @@ grub_video_fb_blit_source (struct grub_video_fbblit_info *source,
       y = 0;
     }
 
-  /* Do not allow drawing out of viewport.  */
-  if ((x + width) > framebuffer.render_target->viewport.width)
-    width = framebuffer.render_target->viewport.width - x;
-  if ((y + height) > framebuffer.render_target->viewport.height)
-    height = framebuffer.render_target->viewport.height - y;
+  /* Do not allow drawing out of area.  */
+  if ((x + width) > area_width)
+    width = area_width - x;
+  if ((y + height) > area_height)
+    height = area_height - y;
 
   if ((offset_x + width) > source->mode_info->width)
     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;
 
   /* Add viewport offset.  */
-  x += framebuffer.render_target->viewport.x;
-  y += framebuffer.render_target->viewport.y;
+  x += area_x;
+  y += area_y;
 
   /* Use fbblit_info to encapsulate rendering.  */
   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.  */
   target->is_allocated = 1;
 
-  /* Maximize viewport.  */
+  /* Maximize viewport, region and area.  */
   target->viewport.x = 0;
   target->viewport.y = 0;
   target->viewport.width = width;
   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.  */
   target->mode_info.width = width;
   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));
 
-  /* Reset viewport to match new mode.  */
+  /* Reset viewport, region and area to match new mode.  */
   target->viewport.x = 0;
   target->viewport.y = 0;
   target->viewport.width = mode_info->width;
   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.  */
   for (y = 0; y < mode_info->height; y++)
     grub_memset (target->data + mode_info->pitch * y, 0,
index 62b86db2ba790ddedf9e964b8212f353c835ea4d..dede0c37ea3e8a8948cd6535d26d008e117206bc 100644 (file)
@@ -138,6 +138,10 @@ static struct grub_video_adapter grub_video_cbfb_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index a29a15dc3d60b88b87cc44127d928179cd93d8ac..62b5c22451348314d5e1e31de3ad24f859ddf981 100644 (file)
@@ -1214,6 +1214,10 @@ static struct grub_video_adapter grub_video_vbe_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 997e132a288c9c7df0d96a01f0271a2bc9c83c6e..01f47112d3777f1a86782646c5bbdf4a891906b0 100644 (file)
@@ -372,6 +372,10 @@ static struct grub_video_adapter grub_video_vga_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 5c5870278067cbb97f9d54e8f0cd04b0ea2c523d..0b150ec2406275cede7d7e6a02a9f5a6999fe52e 100644 (file)
@@ -328,6 +328,10 @@ static struct grub_video_adapter grub_video_ieee1275_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index ddcf9a39e275cd0989df2fa270c69b1a39d6fe2a..b4da34b5eeb680921ed4302af0a1ab70f34e9443 100644 (file)
@@ -207,6 +207,10 @@ static struct grub_video_adapter grub_video_radeon_fuloong2e_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index c1ae27019c7e53dd03dcb0a622577208b63a4e37..22a0c85a647defb0bdd334e00f13a226aa966e7d 100644 (file)
@@ -420,6 +420,10 @@ static struct grub_video_adapter grub_video_sis315pro_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 441faabd31da0512e4613bbf4c94ac846e799e5a..10c46eb654f79befaa6e9cfb8a85cd2046f1a1da 100644 (file)
@@ -779,6 +779,10 @@ static struct grub_video_adapter grub_video_sm712_adapter =
     .get_palette = grub_video_fb_get_palette,
     .set_viewport = grub_video_fb_set_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_rgb = grub_video_fb_map_rgb,
     .map_rgba = grub_video_fb_map_rgba,
index 5215ac967561f02293a21840a5bfa03b7fa10de4..f252663c108f2117cb8e14019d4774d4abb7b7dd 100644 (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);
 }
 
+/* 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.  */
 grub_video_color_t
 grub_video_map_color (grub_uint32_t color_name)
index 12d164bd6a77a0ca74c5578b071e7881fe49e277..35a80b820bd3733a5233801eb4812d4dbb2b0a06 100644 (file)
@@ -30,13 +30,17 @@ struct grub_video_fbrender_target
      mode_type has been re-adjusted to requested render target settings.  */
   struct grub_video_mode_info mode_info;
 
-  struct
-  {
-    unsigned int x;
-    unsigned int y;
-    unsigned int width;
-    unsigned int height;
-  } viewport;
+  /* We should not draw outside of viewport.  */
+  grub_video_rect_t viewport;
+  /* Set region to make a re-draw of a part of the screen.  */
+  grub_video_rect_t region;
+  /* Should be set to 0 if the viewport is inside of the region.  */
+  int area_enabled;
+  /* 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
      when render target is destroyed.  */
index 6f818627e55640be25435a9a52933b08df18fb28..7504c8047a7d4027481bdeab8f26a87cf5993e43 100644 (file)
@@ -248,4 +248,15 @@ grub_video_have_common_points (const grub_video_rect_t *a,
   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 */
index 5dd99c13643aa083ebdbf024ec81d051ce24bd0d..601261e15c52f9003c5f518879ac7a3042168386 100644 (file)
@@ -301,6 +301,11 @@ typedef enum grub_video_adapter_prio
     GRUB_VIDEO_ADAPTER_PRIO_NATIVE = 100
   } 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
 {
@@ -341,6 +346,16 @@ struct grub_video_adapter
   grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y,
                               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_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 *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_rgb) (grub_uint8_t red,
index d1560d982dd3779d940f9d168e9739abe185cca5..4a64fb8b704fe2770007bcea67e94581fce756e6 100644 (file)
@@ -58,6 +58,22 @@ EXPORT_FUNC(grub_video_fb_get_viewport) (unsigned int *x, unsigned int *y,
                                         unsigned int *width,
                                         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
 EXPORT_FUNC(grub_video_fb_map_color) (grub_uint32_t color_name);