diff --git a/commands/videotest.c b/commands/videotest.c index 6fe4b9b..8434b1f 100644 --- a/commands/videotest.c +++ b/commands/videotest.c @@ -34,10 +34,10 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), return grub_errno; grub_video_color_t color; - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; + int x; + int y; + int width; + int height; int i; grub_font_t sansbig; grub_font_t sans; diff --git a/include/grub/fbfill.h b/include/grub/fbfill.h index c85fa12..b60a7ba 100644 --- a/include/grub/fbfill.h +++ b/include/grub/fbfill.h @@ -32,10 +32,10 @@ struct grub_video_fbrender_target struct { - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; + int x; + int y; + int width; + int height; } viewport; /* Indicates whether the data has been allocated by us and must be freed diff --git a/include/grub/video.h b/include/grub/video.h index 4145db4..c24b44b 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -184,11 +184,9 @@ struct grub_video_adapter grub_err_t (*get_palette) (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data); - grub_err_t (*set_viewport) (unsigned int x, unsigned int y, - unsigned int width, unsigned int height); + grub_err_t (*set_viewport) (int x, int y, int width, int height); - grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y, - unsigned int *width, unsigned int *height); + grub_err_t (*get_viewport) (int *x, int *y, int *width, int *height); grub_video_color_t (*map_color) (grub_uint32_t color_name); @@ -203,17 +201,17 @@ struct grub_video_adapter grub_uint8_t *blue, grub_uint8_t *alpha); grub_err_t (*fill_rect) (grub_video_color_t color, int x, int y, - unsigned int width, unsigned int height); + int width, int height); grub_err_t (*blit_bitmap) (struct grub_video_bitmap *bitmap, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height); + int width, int height); grub_err_t (*blit_render_target) (struct grub_video_render_target *source, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height); + int width, int height); grub_err_t (*scroll) (grub_video_color_t color, int dx, int dy); @@ -258,11 +256,11 @@ grub_err_t grub_video_set_palette (unsigned int start, unsigned int count, grub_err_t grub_video_get_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data); -grub_err_t grub_video_set_viewport (unsigned int x, unsigned int y, - unsigned int width, unsigned int height); +grub_err_t grub_video_set_viewport (int x, int y, + int width, int height); -grub_err_t grub_video_get_viewport (unsigned int *x, unsigned int *y, - unsigned int *width, unsigned int *height); +grub_err_t grub_video_get_viewport (int *x, int *y, + int *width, int *height); grub_video_color_t grub_video_map_color (grub_uint32_t color_name); @@ -277,19 +275,18 @@ grub_err_t grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *blue, grub_uint8_t *alpha); grub_err_t grub_video_fill_rect (grub_video_color_t color, int x, int y, - unsigned int width, unsigned int height); + int width, int height); grub_err_t grub_video_blit_bitmap (struct grub_video_bitmap *bitmap, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height); + int width, int height); grub_err_t grub_video_blit_render_target (struct grub_video_render_target *source, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, - unsigned int height); + int width, int height); grub_err_t grub_video_scroll (grub_video_color_t color, int dx, int dy); diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h index 850946d..f1aa295 100644 --- a/include/grub/video_fb.h +++ b/include/grub/video_fb.h @@ -36,6 +36,22 @@ struct grub_video_fbblit_info; struct grub_video_fbrender_target; +/* make width and height of a rectangle non-negative */ +static inline grub_err_t grub_fb_norm_rect(int *x, int *y, int *width, int *height) +{ + if(*width < 0) + { + *width = -*width; + *x -= *width - 1; + } + if(*height < 0) + { + *height = -*height; + *y -= *height - 1; + } + return GRUB_ERR_NONE; +} + #define GRUB_VIDEO_FBSTD_NUMCOLORS 16 extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS]; @@ -55,11 +71,11 @@ grub_err_t grub_video_fb_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data); grub_err_t -grub_video_fb_set_viewport (unsigned int x, unsigned int y, - unsigned int width, unsigned int height); +grub_video_fb_set_viewport (int x, int y, + int width, int height); grub_err_t -grub_video_fb_get_viewport (unsigned int *x, unsigned int *y, - unsigned int *width, unsigned int *height); +grub_video_fb_get_viewport (int *x, int *y, + int *width, int *height); grub_video_color_t grub_video_fb_map_color (grub_uint32_t color_name); @@ -85,19 +101,19 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source, grub_err_t grub_video_fb_fill_rect (grub_video_color_t color, int x, int y, - unsigned int width, unsigned int height); + int width, int height); grub_err_t grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height); + int width, int height); grub_err_t grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height); + int width, int height); grub_err_t grub_video_fb_scroll (grub_video_color_t color, int dx, int dy); diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c index 5f2917d..2fb108e 100644 --- a/video/fb/video_fb.c +++ b/video/fb/video_fb.c @@ -117,27 +117,27 @@ grub_video_fb_set_palette (unsigned int start, unsigned int count, } grub_err_t -grub_video_fb_set_viewport (unsigned int x, unsigned int y, - unsigned int width, unsigned int height) +grub_video_fb_set_viewport (int x, int y, int width, int height) { + grub_fb_norm_rect(&x, &y, &width, &height); /* Make sure viewport is withing screen dimensions. If viewport was set to be out of the region, mark its size as zero. */ - if (x > render_target->mode_info.width) + if (x > (int)render_target->mode_info.width) { x = 0; width = 0; } - if (y > render_target->mode_info.height) + if (y > (int)render_target->mode_info.height) { y = 0; height = 0; } - if (x + width > render_target->mode_info.width) + if (x + width > (int)render_target->mode_info.width) width = render_target->mode_info.width - x; - if (y + height > render_target->mode_info.height) + if (y + height > (int)render_target->mode_info.height) height = render_target->mode_info.height - y; render_target->viewport.x = x; @@ -149,8 +149,7 @@ grub_video_fb_set_viewport (unsigned int x, unsigned int y, } grub_err_t -grub_video_fb_get_viewport (unsigned int *x, unsigned int *y, - unsigned int *width, unsigned int *height) +grub_video_fb_get_viewport (int *x, int *y, int *width, int *height) { if (x) *x = render_target->viewport.x; if (y) *y = render_target->viewport.y; @@ -399,14 +398,15 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source, grub_err_t grub_video_fb_fill_rect (grub_video_color_t color, int x, int y, - unsigned int width, unsigned int height) + int width, int height) { struct grub_video_fbblit_info target; + grub_fb_norm_rect(&x, &y, &width, &height); /* Make sure there is something to do. */ - if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0)) + if ((x >= render_target->viewport.width) || (x + width < 0)) return GRUB_ERR_NONE; - if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + if ((y >= render_target->viewport.height) || (y + height < 0)) return GRUB_ERR_NONE; /* Do not allow drawing out of viewport. */ @@ -485,7 +485,7 @@ static void common_blitter (struct grub_video_fbblit_info *target, struct grub_video_fbblit_info *source, enum grub_video_blit_operators oper, int x, int y, - unsigned int width, unsigned int height, + int width, int height, int offset_x, int offset_y) { if (oper == GRUB_VIDEO_BLIT_REPLACE) @@ -751,27 +751,34 @@ grub_err_t grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height) + int width, int height) { struct grub_video_fbblit_info source; struct grub_video_fbblit_info target; + int src_x = offset_x; + int src_y = offset_y; + + /* Normalize source rectangle and shift target insert point accordingly. */ + grub_fb_norm_rect(&offset_x, &offset_y, &width, &height); + x += offset_x - src_x; + y += offset_y - src_y; /* Make sure there is something to do. */ if ((width == 0) || (height == 0)) return GRUB_ERR_NONE; - if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0)) + if ((x >= render_target->viewport.width) || (x + width < 0)) return GRUB_ERR_NONE; - if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + if ((y >= render_target->viewport.height) || (y + height < 0)) return GRUB_ERR_NONE; if ((x + (int)bitmap->mode_info.width) < 0) return GRUB_ERR_NONE; if ((y + (int)bitmap->mode_info.height) < 0) return GRUB_ERR_NONE; if ((offset_x >= (int)bitmap->mode_info.width) - || (offset_x + (int)width < 0)) + || (offset_x + width < 0)) return GRUB_ERR_NONE; if ((offset_y >= (int)bitmap->mode_info.height) - || (offset_y + (int)height < 0)) + || (offset_y + height < 0)) return GRUB_ERR_NONE; /* If we have negative coordinates, optimize drawing to minimum. */ @@ -809,16 +816,16 @@ grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap, if ((y + height) > render_target->viewport.height) height = render_target->viewport.height - y; - if ((offset_x + width) > bitmap->mode_info.width) + if ((offset_x + width) > (int)bitmap->mode_info.width) width = bitmap->mode_info.width - offset_x; - if ((offset_y + height) > bitmap->mode_info.height) + if ((offset_y + height) > (int)bitmap->mode_info.height) height = bitmap->mode_info.height - offset_y; /* Limit drawing to source render target dimensions. */ - if (width > bitmap->mode_info.width) + if (width > (int)bitmap->mode_info.width) width = bitmap->mode_info.width; - if (height > bitmap->mode_info.height) + if (height > (int)bitmap->mode_info.height) height = bitmap->mode_info.height; /* Add viewport offset. */ @@ -842,27 +849,34 @@ grub_err_t grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height) + int width, int height) { struct grub_video_fbblit_info source_info; struct grub_video_fbblit_info target_info; + int src_x = offset_x; + int src_y = offset_y; + + /* Normalize source rectangle and shift target insert point accordingly. */ + grub_fb_norm_rect(&offset_x, &offset_y, &width, &height); + x += offset_x - src_x; + y += offset_y - src_y; /* Make sure there is something to do. */ if ((width == 0) || (height == 0)) return GRUB_ERR_NONE; - if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0)) + if ((x >= render_target->viewport.width) || (x + width < 0)) return GRUB_ERR_NONE; - if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + if ((y >= render_target->viewport.height) || (y + height < 0)) return GRUB_ERR_NONE; if ((x + (int)source->mode_info.width) < 0) return GRUB_ERR_NONE; if ((y + (int)source->mode_info.height) < 0) return GRUB_ERR_NONE; if ((offset_x >= (int)source->mode_info.width) - || (offset_x + (int)width < 0)) + || (offset_x + width < 0)) return GRUB_ERR_NONE; if ((offset_y >= (int)source->mode_info.height) - || (offset_y + (int)height < 0)) + || (offset_y + height < 0)) return GRUB_ERR_NONE; /* If we have negative coordinates, optimize drawing to minimum. */ @@ -900,16 +914,16 @@ grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source, if ((y + height) > render_target->viewport.height) height = render_target->viewport.height - y; - if ((offset_x + width) > source->mode_info.width) + if ((offset_x + width) > (int)source->mode_info.width) width = source->mode_info.width - offset_x; - if ((offset_y + height) > source->mode_info.height) + if ((offset_y + height) > (int)source->mode_info.height) height = source->mode_info.height - offset_y; /* Limit drawing to source render target dimensions. */ - if (width > source->mode_info.width) + if (width > (int)source->mode_info.width) width = source->mode_info.width; - if (height > source->mode_info.height) + if (height > (int)source->mode_info.height) height = source->mode_info.height; /* Add viewport offset. */ @@ -969,8 +983,8 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) } /* 2. Check if there is need to copy data. */ - if ((grub_abs (dx) < render_target->viewport.width) - && (grub_abs (dy) < render_target->viewport.height)) + if (((int)grub_abs (dx) < render_target->viewport.width) + && ((int)grub_abs (dy) < render_target->viewport.height)) { /* 3. Move data in render target. */ struct grub_video_fbblit_info target; @@ -1011,7 +1025,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) grub_video_fb_fill_rect (color, 0, 0, render_target->viewport.width, dy); else if (dy < 0) { - if (render_target->viewport.height < grub_abs (dy)) + if (render_target->viewport.height < (int)grub_abs (dy)) dy = -render_target->viewport.height; grub_video_fb_fill_rect (color, 0, render_target->viewport.height + dy, @@ -1024,7 +1038,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) dx, render_target->viewport.height); else if (dx < 0) { - if (render_target->viewport.width < grub_abs (dx)) + if (render_target->viewport.width < (int)grub_abs (dx)) dx = -render_target->viewport.width; grub_video_fb_fill_rect (color, render_target->viewport.width + dx, 0, diff --git a/video/video.c b/video/video.c index c1d66bd..29d760f 100644 --- a/video/video.c +++ b/video/video.c @@ -227,8 +227,7 @@ grub_video_get_palette (unsigned int start, unsigned int count, /* Set viewport dimensions. */ grub_err_t -grub_video_set_viewport (unsigned int x, unsigned int y, - unsigned int width, unsigned int height) +grub_video_set_viewport (int x, int y, int width, int height) { if (! grub_video_adapter_active) return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); @@ -238,8 +237,7 @@ grub_video_set_viewport (unsigned int x, unsigned int y, /* Get viewport dimensions. */ grub_err_t -grub_video_get_viewport (unsigned int *x, unsigned int *y, - unsigned int *width, unsigned int *height) +grub_video_get_viewport (int *x, int *y, int *width, int *height) { if (! grub_video_adapter_active) return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); @@ -297,7 +295,7 @@ grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red, /* Fill rectangle using specified color. */ grub_err_t grub_video_fill_rect (grub_video_color_t color, int x, int y, - unsigned int width, unsigned int height) + int width, int height) { if (! grub_video_adapter_active) return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); @@ -310,7 +308,7 @@ grub_err_t grub_video_blit_bitmap (struct grub_video_bitmap *bitmap, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height) + int width, int height) { if (! grub_video_adapter_active) return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); @@ -325,7 +323,7 @@ grub_err_t grub_video_blit_render_target (struct grub_video_render_target *target, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height) + int width, int height) { if (! grub_video_adapter_active) return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");