Add optional framebuffer rotation, which allows the user to specify the 
display output rotation

   MODIFIED:

fbutil.h include/grub - Add function declarations. see below.

video.h include/grub

   struct grub_video_mode_info - Add int original_width, int original_height,
   enum grub_video_rotation rotation.

fbblit.c grub-core/video/fb

   Modify grub_video_fb_dispatch_blit() to rotate blit coordinates.
   TODO: currently only the generic(slow) blitting operation is used when 
rotation is specified. This should be implementd for every blitting mode and 
operation.

fbfill.c grub-core/video/fb

   Modify grub_video_fb_fill_dispatch() to rotate fill coordinates.

fbutil.c grub-core/video/fb

   Add functions trans_x and trans_y to translate coordinates depending on 
mode_info.rotation
   Add function grub_video_transform_rectangle to transform video_rect 
depending on mode_info

video_fb.c grub-core/video/fb

   Modify functions:

      dirty() to rotate dirty video_rect

      grub_video_fb_scroll() to rotate scroll

      grub_video_fb_create_render_target - use no rotation via mode_info by 
default. Render
      target's(such as text_layers) get rotated on the final blit to the actual 
framebuffer,    thus we want a mode_info with NO rotation set to prevent 
"double rotation's".

      grub_video_fb_create_render_target_from_pointer - Check for rotation 
grub_env_var and set mode_info rotation, viewport, area, width, and height for 
render_target depending on the rotation specified.

      Other functions - update to use original_width or original_height where 
appropriate.


Signed-off-by: kbader94 <kyle.bade...@gmail.com>
---
 grub-core/video/fb/fbblit.c   |  71 ++++++++++++++++++++--
 grub-core/video/fb/fbfill.c   |  28 ++++++---
 grub-core/video/fb/fbutil.c   |  61 +++++++++++++++++++
 grub-core/video/fb/video_fb.c | 107 +++++++++++++++++++++++-----------
 include/grub/fbutil.h         |   9 +++
 include/grub/video.h          |  20 ++++++-
 6 files changed, 247 insertions(+), 49 deletions(-)

diff --git a/grub-core/video/fb/fbblit.c b/grub-core/video/fb/fbblit.c
index 1010ef393..5dda0ffdb 100644
--- a/grub-core/video/fb/fbblit.c
+++ b/grub-core/video/fb/fbblit.c
@@ -62,7 +62,8 @@ grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
          dst_color = grub_video_fb_map_rgba (src_red, src_green,
                                              src_blue, src_alpha);
 
-         set_pixel (dst, x + i, y + j, dst_color);
+         set_pixel (dst, x + trans_x(i, j, dst->mode_info), 
+               y + trans_y(i,j, dst->mode_info), dst_color);
        }
     }
 }
@@ -1195,11 +1196,11 @@ grub_video_fbblit_blend (struct grub_video_fbblit_info 
*dst,
             {
               dst_color = grub_video_fb_map_rgba (src_red, src_green,
                                                  src_blue, src_alpha);
-              set_pixel (dst, x + i, y + j, dst_color);
+              set_pixel (dst, x + trans_x(i, j, dst->mode_info), y + 
trans_y(i,j, dst->mode_info), dst_color);
               continue;
             }
 
-          dst_color = get_pixel (dst, x + i, y + j);
+          dst_color = get_pixel (dst, x + trans_x(i, j, dst->mode_info), y + 
trans_y(i,j, dst->mode_info));
 
           grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
                                         &dst_green, &dst_blue, &dst_alpha);
@@ -1212,7 +1213,7 @@ grub_video_fbblit_blend (struct grub_video_fbblit_info 
*dst,
           dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
                                              dst_alpha);
 
-          set_pixel (dst, x + i, y + j, dst_color);
+          set_pixel (dst, x + trans_x(i, j, dst->mode_info), y + trans_y(i,j, 
dst->mode_info), dst_color);
         }
     }
 }
@@ -1936,6 +1937,68 @@ grub_video_fb_dispatch_blit (struct 
grub_video_fbblit_info *target,
                             unsigned int width, unsigned int height,
                             int offset_x, int offset_y)
 {
+  if (target->mode_info->rotation == GRUB_VIDEO_ROTATE_90)
+    {
+      int nx = y;
+      int ny = target->mode_info->width - x - 1;
+      if (oper == GRUB_VIDEO_BLIT_REPLACE)
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  
*/
+         grub_video_fbblit_replace (target, source, nx, ny, width, height,
+                                       offset_x, offset_y);
+         return;
+       }
+      else
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  
*/
+         grub_video_fbblit_blend (target, source, nx, ny, width, height,
+                                     offset_x, offset_y);
+         return;
+       }
+    }
+
+  if (target->mode_info->rotation == GRUB_VIDEO_ROTATE_180)
+    {
+      int nx = target->mode_info->width - x - 1;
+      int ny = target->mode_info->height - y - 1;
+      if (oper == GRUB_VIDEO_BLIT_REPLACE)
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  
*/
+         grub_video_fbblit_replace (target, source, nx, ny, width, height,
+                                        offset_x, offset_y);
+         return;
+       }
+      else
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  
*/
+         grub_video_fbblit_blend (target, source, nx, ny, width, height,
+                                      offset_x, offset_y);
+         return;
+       }
+
+      
+    }
+
+  if (target->mode_info->rotation == GRUB_VIDEO_ROTATE_270)
+    {
+      int nx = target->mode_info->height - y - 1;
+      int ny = x;
+      if (oper == GRUB_VIDEO_BLIT_REPLACE)
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  
*/
+         grub_video_fbblit_replace (target, source, nx, ny, width, height,
+                                        offset_x, offset_y);
+         return;
+       }
+      else
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  
*/
+         grub_video_fbblit_blend (target, source, nx, ny, width, height,
+                                      offset_x, offset_y);
+         return;
+       }
+    }
+
   if (oper == GRUB_VIDEO_BLIT_REPLACE)
     {
       /* Try to figure out more optimized version for replace operator.  */
diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c
index 49fa16b92..cab4d8acc 100644
--- a/grub-core/video/fb/fbfill.c
+++ b/grub-core/video/fb/fbfill.c
@@ -185,28 +185,38 @@ grub_video_fb_fill_dispatch (struct 
grub_video_fbblit_info *target,
                             grub_video_color_t color, int x, int y,
                             unsigned int width, unsigned int height)
 {
+  grub_video_rect_t orig = {
+    .x = x,
+    .y = y,
+    .width = width,
+    .height = height
+  };
+  grub_video_rect_t tran = grub_video_transform_rectangle (orig, 
target->mode_info);
+  
   /* Try to figure out more optimized version.  Note that color is already
      mapped to target format so we can make assumptions based on that.  */
   switch (target->mode_info->bytes_per_pixel)
     {
     case 4:
-      grub_video_fbfill_direct32 (target, color, x, y,
-                                 width, height);
+      grub_video_fbfill_direct32 (target, color, tran.x, tran.y,
+                                 tran.width, tran.height);
       return;
     case 3:
-      grub_video_fbfill_direct24 (target, color, x, y,
-                                 width, height);
+      grub_video_fbfill_direct24 (target, color, tran.x, tran.y,
+                                 tran.width, tran.height);
+      return;
       return;
     case 2:
-      grub_video_fbfill_direct16 (target, color, x, y,
-                                        width, height);
+      grub_video_fbfill_direct16 (target, color, tran.x, tran.y,
+                                 tran.width, tran.height);
       return;
     case 1:
-      grub_video_fbfill_direct8 (target, color, x, y,
-                                      width, height);
+      grub_video_fbfill_direct8 (target, color, tran.x, tran.y,
+                                 tran.width, tran.height);
       return;
     }
 
   /* No optimized version found, use default (slow) filler.  */
-  grub_video_fbfill (target, color, x, y, width, height);
+  grub_video_fbfill  (target, color, tran.x, tran.y,
+                                 tran.width, tran.height);
 }
diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c
index 25ef39f47..368356fd7 100644
--- a/grub-core/video/fb/fbutil.c
+++ b/grub-core/video/fb/fbutil.c
@@ -149,3 +149,64 @@ set_pixel (struct grub_video_fbblit_info *source,
       break;
     }
 }
+
+int 
+trans_x(int x,int y, struct grub_video_mode_info *mode_info)
+{
+    switch (mode_info->rotation) {
+        case GRUB_VIDEO_ROTATE_90:
+            return y;
+        case GRUB_VIDEO_ROTATE_180:
+            return -x;
+        case GRUB_VIDEO_ROTATE_270:
+            return -y;
+        case GRUB_VIDEO_ROTATE_NONE:
+        default:
+            return x;
+    }
+}
+
+int 
+trans_y(int x, int y, struct grub_video_mode_info *mode_info)
+{
+    switch (mode_info->rotation) {
+        case GRUB_VIDEO_ROTATE_90:
+            return -x;
+        case GRUB_VIDEO_ROTATE_180:
+            return -y;
+        case GRUB_VIDEO_ROTATE_270:
+            return x;
+        case GRUB_VIDEO_ROTATE_NONE:
+        default:
+            return y;
+    }
+}
+
+grub_video_rect_t grub_video_transform_rectangle (grub_video_rect_t r, const 
struct grub_video_mode_info *mode_info)
+{
+  grub_video_rect_t n;
+  switch (mode_info->rotation)
+    {
+    case GRUB_VIDEO_ROTATE_NONE:
+      return r;
+    case GRUB_VIDEO_ROTATE_90:
+      n.width = r.height;
+      n.height = r.width;
+      n.x = r.y;
+      n.y = mode_info->width - r.x - r.width;
+      return n;
+    case GRUB_VIDEO_ROTATE_180:
+      n.width = r.width;
+      n.height = r.height;
+      n.x = mode_info->width - r.x - r.width;
+      n.y = mode_info->height - r.y - r.height;
+      return n;
+    case GRUB_VIDEO_ROTATE_270:
+      n.width = r.height;
+      n.height = r.width;
+      n.x = mode_info->height - r.y - r.height;
+      n.y = r.x;
+      return n;
+    }
+  return r;
+}
\ No newline at end of file
diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c
index d17c47b11..377a9179d 100644
--- a/grub-core/video/fb/video_fb.c
+++ b/grub-core/video/fb/video_fb.c
@@ -26,6 +26,7 @@
 #include <grub/bitmap.h>
 #include <grub/dl.h>
 #include <grub/safemath.h>
+#include <grub/env.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -826,15 +827,17 @@ grub_video_fb_unmap_color_int (struct 
grub_video_fbblit_info * source,
 static void
 dirty (int x, int y, int width, int height)
 {
-  
+
   grub_video_rect_t *current_dirty = &framebuffer.current_dirty;
-  grub_video_rect_t dirty_rect = {
+  grub_video_rect_t additive_rect = {
     .x = x,
     .y = y,
     .width = width,
     .height = height
   };
 
+  grub_video_rect_t dirty_rect = grub_video_transform_rectangle 
(additive_rect, &framebuffer.render_target->mode_info);
+
   if (framebuffer.render_target != framebuffer.back_target)
     return;
 
@@ -1063,6 +1066,8 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, 
int dy)
 {
   int width;
   int height;
+  int tx; /* transformed scroll coords */
+  int ty; /* transformed scroll coords */
   int src_x;
   int src_y;
   int dst_x;
@@ -1072,39 +1077,41 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, 
int dy)
   if ((dx == 0) && (dy == 0))
     return GRUB_ERR_NONE;
 
-  width = framebuffer.render_target->viewport.width - grub_abs (dx);
-  height = framebuffer.render_target->viewport.height - grub_abs (dy);
+  tx = trans_x(dx,dy, &framebuffer.render_target->mode_info);
+  ty = trans_y(dx,dy, &framebuffer.render_target->mode_info);
+  width = framebuffer.render_target->mode_info.original_width - grub_abs (tx);
+  height = framebuffer.render_target->mode_info.original_height - grub_abs 
(ty);
 
   dirty (framebuffer.render_target->viewport.x,
         framebuffer.render_target->viewport.y,
-   framebuffer.render_target->viewport.width,
+        framebuffer.render_target->viewport.width,
         framebuffer.render_target->viewport.height);
 
-  if (dx < 0)
+  if (tx < 0)
     {
-      src_x = framebuffer.render_target->viewport.x - dx;
+      src_x = framebuffer.render_target->viewport.x - tx;
       dst_x = framebuffer.render_target->viewport.x;
     }
   else
     {
       src_x = framebuffer.render_target->viewport.x;
-      dst_x = framebuffer.render_target->viewport.x + dx;
+      dst_x = framebuffer.render_target->viewport.x + tx;
     }
 
-  if (dy < 0)
+  if (ty < 0)
     {
-      src_y = framebuffer.render_target->viewport.y - dy;
+      src_y = framebuffer.render_target->viewport.y - ty;
       dst_y = framebuffer.render_target->viewport.y;
     }
   else
     {
       src_y = framebuffer.render_target->viewport.y;
-      dst_y = framebuffer.render_target->viewport.y + dy;
+      dst_y = framebuffer.render_target->viewport.y + ty;
     }
 
   /* 2. Check if there is need to copy data.  */
-  if ((grub_abs (dx) < framebuffer.render_target->viewport.width)
-       && (grub_abs (dy) < framebuffer.render_target->viewport.height))
+  if ((grub_abs (tx) < framebuffer.render_target->viewport.width)
+       && (grub_abs (ty) < framebuffer.render_target->viewport.height))
     {
       /* 3. Move data in render target.  */
       struct grub_video_fbblit_info target;
@@ -1119,7 +1126,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, 
int dy)
       linelen = width * target.mode_info->bytes_per_pixel;
 #define DO_SCROLL                                                    \
       /* Check vertical direction of the move.  */                   \
-      if (dy < 0 || (dy == 0 && dx < 0))                             \
+      if (ty < 0 || (ty == 0 && tx < 0))                             \
        {                                                            \
          dst = (void *) grub_video_fb_get_video_ptr (&target,       \
                                                      dst_x, dst_y); \
@@ -1245,6 +1252,9 @@ grub_video_fb_create_render_target (struct 
grub_video_fbrender_target **result,
   /* TODO: Implement other types too.
      Currently only 32bit render targets are supported.  */
 
+/* only used by text_layers, so do not rotate */
+  target->mode_info.rotation = GRUB_VIDEO_ROTATE_NONE;
+
   /* Mark render target as allocated.  */
   target->is_allocated = 1;
 
@@ -1270,6 +1280,8 @@ grub_video_fb_create_render_target (struct 
grub_video_fbrender_target **result,
   /* Setup render target format.  */
   target->mode_info.width = width;
   target->mode_info.height = height;
+  target->mode_info.original_width = width;
+  target->mode_info.original_height = height;
   switch (mode_type)
     {
     case GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
@@ -1332,6 +1344,7 @@ grub_video_fb_create_render_target_from_pointer (struct 
grub_video_fbrender_targ
 {
   struct grub_video_fbrender_target *target;
   unsigned y;
+  const char *rot_env;
 
 #ifndef GRUB_HAVE_UNALIGNED_ACCESS
   if (!(mode_info->bytes_per_pixel & (mode_info->bytes_per_pixel - 1))
@@ -1352,30 +1365,53 @@ grub_video_fb_create_render_target_from_pointer (struct 
grub_video_fbrender_targ
   target->data = ptr;
 
   grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info));
+  rot_env = grub_env_get("rotation");
+
+  if (!rot_env) {
+        target->mode_info.rotation = GRUB_VIDEO_ROTATE_NONE;
+    } else if (grub_strcmp(rot_env, "90") == 0) {
+        target->mode_info.rotation = GRUB_VIDEO_ROTATE_90;
+    } else if (grub_strcmp(rot_env, "180") == 0) {
+        target->mode_info.rotation = GRUB_VIDEO_ROTATE_180;
+    } else if (grub_strcmp(rot_env, "270") == 0) {
+        target->mode_info.rotation = GRUB_VIDEO_ROTATE_270;
+    } else {
+        target->mode_info.rotation = GRUB_VIDEO_ROTATE_NONE;
+    }
+
+  target->mode_info.original_width = mode_info->width;
+  target->mode_info.original_height = mode_info->height;
+
+  if (target->mode_info.rotation == GRUB_VIDEO_ROTATE_90
+      || target->mode_info.rotation == GRUB_VIDEO_ROTATE_270)
+    {
+      target->mode_info.width = target->mode_info.original_height;
+      target->mode_info.height = target->mode_info.original_width;
+    }
 
   /* 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->viewport.width = target->mode_info.width;
+  target->viewport.height = target->mode_info.height;
 
   target->region.x = 0;
   target->region.y = 0;
-  target->region.width = mode_info->width;
-  target->region.height = mode_info->height;
+  target->region.width = target->mode_info.width;
+  target->region.height = target->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.width = target->mode_info.width;
+  target->area.height = target->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++)
+  for (y = 0; y < target->mode_info.original_height; y++)
     grub_memset (target->data + mode_info->pitch * y, 0,
-                mode_info->bytes_per_pixel * mode_info->width);
+                mode_info->bytes_per_pixel * target->mode_info.original_width);
 
   /* Save result to caller.  */
   *result = target;
@@ -1455,9 +1491,9 @@ doublebuf_blit_update_screen (void)
   }
 
   /* reset current_dirty rect */
-  framebuffer.current_dirty.y = framebuffer.back_target->mode_info.height;
+  framebuffer.current_dirty.y = 
framebuffer.back_target->mode_info.original_height;
   framebuffer.current_dirty.height = 0;
-  framebuffer.current_dirty.x = framebuffer.back_target->mode_info.width;
+  framebuffer.current_dirty.x = 
framebuffer.back_target->mode_info.original_width;
   framebuffer.current_dirty.width = 0;
 
   return GRUB_ERR_NONE;
@@ -1491,9 +1527,9 @@ grub_video_fb_doublebuf_blit_init (struct 
grub_video_fbrender_target **back,
   framebuffer.pages[0] = framebuf;
   framebuffer.displayed_page = 0;
   framebuffer.render_page = 0;
-  framebuffer.current_dirty.y = framebuffer.back_target->mode_info.height;
+  framebuffer.current_dirty.y = 
framebuffer.back_target->mode_info.original_height;
   framebuffer.current_dirty.height = 0;
-  framebuffer.current_dirty.x = framebuffer.back_target->mode_info.width;
+  framebuffer.current_dirty.x = 
framebuffer.back_target->mode_info.original_width;
   framebuffer.current_dirty.width = 0;
 
   return GRUB_ERR_NONE;
@@ -1546,9 +1582,9 @@ doublebuf_pageflipping_update_screen (void)
 
   /* reset current_dirty rect */
   framebuffer.previous_dirty = framebuffer.current_dirty;
-  framebuffer.current_dirty.y = framebuffer.back_target->mode_info.height;
+  framebuffer.current_dirty.y = 
framebuffer.back_target->mode_info.original_height;
   framebuffer.current_dirty.height = 0;
-  framebuffer.current_dirty.x = framebuffer.back_target->mode_info.width;
+  framebuffer.current_dirty.x = 
framebuffer.back_target->mode_info.original_width;
   framebuffer.current_dirty.width = 0;
 
   /* Swap the page numbers in the framebuffer struct.  */
@@ -1609,15 +1645,15 @@ doublebuf_pageflipping_init (struct 
grub_video_mode_info *mode_info,
   framebuffer.pages[1] = page1_ptr;
 
   /* reset current_dirty rect */
-  framebuffer.current_dirty.y = framebuffer.back_target->mode_info.height;
+  framebuffer.current_dirty.y = 
framebuffer.back_target->mode_info.original_height;
   framebuffer.current_dirty.height = 0;
-  framebuffer.current_dirty.x = framebuffer.back_target->mode_info.width;
+  framebuffer.current_dirty.x = 
framebuffer.back_target->mode_info.original_width;
   framebuffer.current_dirty.width = 0;
 
    /* reset previous_dirty rect */
-  framebuffer.previous_dirty.y = framebuffer.back_target->mode_info.height;
+  framebuffer.previous_dirty.y = 
framebuffer.back_target->mode_info.original_height;
   framebuffer.previous_dirty.height = 0;
-  framebuffer.previous_dirty.x = framebuffer.back_target->mode_info.width;
+  framebuffer.previous_dirty.x = 
framebuffer.back_target->mode_info.original_width;
   framebuffer.previous_dirty.width = 0;
 
   /* Set the framebuffer memory data pointer and display the right page.  */
@@ -1705,9 +1741,9 @@ grub_video_fb_setup (unsigned int mode_type, unsigned int 
mode_mask,
   framebuffer.render_page = 0;
   framebuffer.set_page = 0;
  /* reset transformed_add_rect */
-  framebuffer.current_dirty.y = framebuffer.back_target->mode_info.height;
+  framebuffer.current_dirty.y = 
framebuffer.back_target->mode_info.original_height;
   framebuffer.current_dirty.height = 0;
-  framebuffer.current_dirty.x = framebuffer.back_target->mode_info.width;
+  framebuffer.current_dirty.x = 
framebuffer.back_target->mode_info.original_width;
   framebuffer.current_dirty.width = 0;
 
   mode_info->mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
@@ -1739,6 +1775,9 @@ grub_video_fb_get_info_and_fini (struct 
grub_video_mode_info *mode_info,
   grub_memcpy (mode_info, &(framebuffer.back_target->mode_info),
               sizeof (*mode_info));
 
+  mode_info->width = framebuffer.back_target->mode_info.original_width;
+  mode_info->height = framebuffer.back_target->mode_info.original_height;
+
   /* We are about to load a kernel.  Switch back to page zero, since some
      kernel drivers expect that.  */
   if (framebuffer.set_page && framebuffer.displayed_page != 0)
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
index 78a1ab3b4..ad625bff9 100644
--- a/include/grub/fbutil.h
+++ b/include/grub/fbutil.h
@@ -61,4 +61,13 @@ grub_video_color_t get_pixel (struct grub_video_fbblit_info 
*source,
 void set_pixel (struct grub_video_fbblit_info *source,
                 unsigned int x, unsigned int y, grub_video_color_t color);
 
+int 
+trans_x(int x,int y, struct grub_video_mode_info *mode_info);
+
+int 
+trans_y(int x, int y, struct grub_video_mode_info *mode_info);
+
+grub_video_rect_t grub_video_transform_rectangle (grub_video_rect_t r, 
+                                                  const struct 
grub_video_mode_info *mode_info);
+
 #endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */
diff --git a/include/grub/video.h b/include/grub/video.h
index 9dac0f379..f05e70b26 100644
--- a/include/grub/video.h
+++ b/include/grub/video.h
@@ -75,6 +75,14 @@ typedef enum grub_video_mode_type
     GRUB_VIDEO_MODE_TYPE_INFO_MASK        = 0x00FF0000,
   } grub_video_mode_type_t;
 
+enum grub_video_rotation
+  {
+    GRUB_VIDEO_ROTATE_NONE,
+    GRUB_VIDEO_ROTATE_90,
+    GRUB_VIDEO_ROTATE_180,
+    GRUB_VIDEO_ROTATE_270
+  };
+
 /* The basic render target representing the whole display.  This always
    renders to the back buffer when double-buffering is in use.  */
 #define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
@@ -122,12 +130,20 @@ enum grub_video_blit_operators
 
 struct grub_video_mode_info
 {
-  /* Width of the screen.  */
+  /* Width of the screen, before the rotation.  */
+  unsigned int original_width;
+
+  /* Height of the screen, before the rotation.  */
+  unsigned int original_height;
+
+  /* Width of the screen, after the rotation.  */
   unsigned int width;
 
-  /* Height of the screen.  */
+  /* Height of the screen, after the rotation.  */
   unsigned int height;
 
+  enum grub_video_rotation rotation;
+
   /* Mode type bitmask.  Contains information like is it Index color or
      RGB mode.  */
   grub_video_mode_type_t mode_type;
-- 
2.34.1


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to