Patch has been remade to meet the requirements.

On Friday, April 26, 2013 05:06:17 PM Vladimir Testov wrote:
> There can be cases when we would like to move terminal window. For example,
> it follows our theme design.
> 
> So,
> 
> options:
> terminal-top
> terminal-left
> terminal-width
> terminal-height
> terminal-border
> 
> (the last is for setting terminal-border width)
> 
> All of these were hard-coded.
> 
> Tested on all cases. Safe. (if some part of the terminal window is going to
> fall of the screen rectangle, parameters will be correspondingly auto-
> adjusted)
> 
> --
> With best regards,
> _______________________________
> Vladimir Testov, ROSA Laboratory.
> www.rosalab.ru
-- 
With best regards,
_______________________________
Vladimir Testov, ROSA Laboratory.
www.rosalab.ru
diff -Naur grub-2.01/docs/grub.texi grub-new/docs/grub.texi
--- grub-2.01/docs/grub.texi	2013-06-25 15:21:25.000000000 +0400
+++ grub-new/docs/grub.texi	2013-06-25 19:50:51.000000000 +0400
@@ -1904,6 +1904,11 @@
 @item desktop-image @tab Specifies the image to use as the background.  It will be scaled to fit the screen size.
 @item desktop-color @tab Specifies the color for the background if *desktop-image* is not specified.
 @item terminal-box @tab Specifies the file name pattern for the styled box slices used for the command line terminal window.  For example, ``terminal-box: terminal_*.png'' will use the images ``terminal_c.png`` as the center area, ``terminal_n.png`` as the north (top) edge, ``terminal_nw.png`` as the northwest (upper left) corner, and so on.  If the image for any slice is not found, it will simply be left empty.
+@item terminal-border @tab Specifies the border width of the terminal window.
+@item terminal-left @tab Specifies the left coordinate of the terminal window.
+@item terminal-top @tab Specifies the top coordinate of the terminal window.
+@item terminal-width @tab Specifies the width of the terminal window.
+@item terminal-height @tab Specifies the height of the terminal window.
 @end multitable
 
 
diff -Naur grub-2.01/grub-core/gfxmenu/theme_loader.c grub-new/grub-core/gfxmenu/theme_loader.c
--- grub-2.01/grub-core/gfxmenu/theme_loader.c	2013-06-25 15:21:25.000000000 +0400
+++ grub-new/grub-core/gfxmenu/theme_loader.c	2013-06-25 19:50:51.000000000 +0400
@@ -32,6 +32,9 @@
 #include <grub/gui.h>
 #include <grub/color.h>
 
+static grub_err_t
+parse_proportional_spec (char *value, signed *abs, grub_fixed_signed_t *prop);
+
 /* Construct a new box widget using ABSPATTERN to find the pixmap files for
    it, storing the new box instance at *BOXPTR.
    PATTERN should be of the form: "(hd0,0)/somewhere/style*.png".
@@ -179,6 +182,56 @@
         if (err != GRUB_ERR_NONE)
           return err;
     }
+  else if (! grub_strcmp ("terminal-border", name))
+    {
+      view->terminal_border = grub_strtoul (value, 0, 10);
+      if (grub_errno)
+        return grub_errno;
+    }
+  else if (! grub_strcmp ("terminal-left", name))
+    {
+      grub_err_t err;
+      grub_fixed_signed_t frac;
+      signed pixels;
+      err = parse_proportional_spec (value, &pixels, &frac);
+      if (err != GRUB_ERR_NONE)
+        return err;
+      view->x = pixels;
+      view->xfrac = frac;
+    }
+  else if (! grub_strcmp ("terminal-top", name))
+    {
+      grub_err_t err;
+      grub_fixed_signed_t frac;
+      signed pixels;
+      err = parse_proportional_spec (value, &pixels, &frac);
+      if (err != GRUB_ERR_NONE)
+        return err;
+      view->y = pixels;
+      view->yfrac = frac;
+    }
+  else if (! grub_strcmp ("terminal-width", name))
+    {
+      grub_err_t err;
+      grub_fixed_signed_t frac;
+      signed pixels;
+      err = parse_proportional_spec (value, &pixels, &frac);
+      if (err != GRUB_ERR_NONE)
+        return err;
+      view->w = pixels;
+      view->wfrac = frac;
+    }
+  else if (! grub_strcmp ("terminal-height", name))
+    {
+      grub_err_t err;
+      grub_fixed_signed_t frac;
+      signed pixels;
+      err = parse_proportional_spec (value, &pixels, &frac);
+      if (err != GRUB_ERR_NONE)
+        return err;
+      view->h = pixels;
+      view->hfrac = frac;
+    }
   else if (! grub_strcmp ("title-text", name))
     {
       grub_free (view->title_text);
diff -Naur grub-2.01/grub-core/gfxmenu/view.c grub-new/grub-core/gfxmenu/view.c
--- grub-2.01/grub-core/gfxmenu/view.c	2013-04-26 23:39:50.000000000 +0400
+++ grub-new/grub-core/gfxmenu/view.c	2013-06-27 16:33:22.759010088 +0400
@@ -40,7 +40,6 @@
 
 static void
 init_terminal (grub_gfxmenu_view_t view);
-static grub_video_rect_t term_rect;
 static grub_gfxmenu_view_t term_view;
 
 /* Create a new view object, loading the theme specified by THEME_PATH and
@@ -71,6 +70,19 @@
   view->screen.width = width;
   view->screen.height = height;
 
+  view->terminal_border = 3;
+
+  /* view->terminal_rect will be defined during execution of init_terminal */
+
+  view->x = 0;
+  view->xfrac = 0;
+  view->y = 0;
+  view->yfrac = 0;
+  view->w = 0;
+  view->wfrac = 0;
+  view->h = 0;
+  view->hfrac = 0;
+
   default_font = grub_font_get ("Unknown Regular 16");
   default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
   default_bg_color = grub_video_rgba_color_rgb (255, 255, 255);
@@ -302,7 +314,7 @@
 grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
 			  const grub_video_rect_t *region)
 {
-  if (grub_video_have_common_points (&term_rect, region))
+  if (grub_video_have_common_points (&view->terminal_rect, region))
     grub_gfxterm_schedule_repaint ();
 
   grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
@@ -386,25 +398,34 @@
   term_box = term_view->terminal_box;
   if (!term_box)
     return;
-  
-  term_box->set_content_size (term_box, term_rect.width,
-			      term_rect.height);
+
+  term_box->set_content_size (term_box, term_view->terminal_rect.width,
+			      term_view->terminal_rect.height);
   
   term_box->draw (term_box,
-		  term_rect.x - term_box->get_left_pad (term_box),
-		  term_rect.y - term_box->get_top_pad (term_box));
+		  term_view->terminal_rect.x - term_box->get_left_pad (term_box),
+		  term_view->terminal_rect.y - term_box->get_top_pad (term_box));
 }
 
 static void
-init_terminal (grub_gfxmenu_view_t view)
+get_min_terminal (grub_font_t terminal_font, int border_width,
+                         unsigned int *min_terminal_width, unsigned int *min_terminal_height)
 {
-  const int border_width = 3;
+  struct grub_font_glyph *glyph;
+  glyph = grub_font_get_glyph (terminal_font, 'M');
+  *min_terminal_width = (glyph? glyph->device_width : 8) * 80 + 2 * border_width;
+  *min_terminal_height = grub_font_get_max_char_height (terminal_font) * 24
+                         + 2 * border_width;
+}
 
+static void
+init_terminal (grub_gfxmenu_view_t view)
+{
+  int border_width = view->terminal_border;
+  grub_video_rect_t screen_rect = view->screen;
   grub_font_t terminal_font;
-
-  unsigned int line_width;
-
-  struct grub_font_glyph *glyph;
+  unsigned int min_terminal_width;
+  unsigned int min_terminal_height;
 
   terminal_font = grub_font_get (view->terminal_font_name);
   if (!terminal_font)
@@ -413,36 +434,78 @@
       return;
     }
 
-  glyph = grub_font_get_glyph (terminal_font, 'M');
-
-  line_width = ((glyph ? glyph->device_width : 8) * 80 + 2 * border_width);
-
-  if (view->screen.width <= line_width)
-    /* The screen is too small. Use all space, except a small border
-       to show the user, it is a window and not full screen: */
-    term_rect.width = view->screen.width - 6 * border_width;
-  else
-    {
-      /* The screen is big enough. Try 70% of the screen width: */
-      term_rect.width = view->screen.width * 7 / 10;
-      /* Make sure, that we use at least the line_width: */
-      if ( term_rect.width < line_width )
-	term_rect.width = line_width;
-    }
-
-  term_rect.height = view->screen.height * 7 / 10;
-
-  term_rect.x = view->screen.x + (view->screen.width  - term_rect.width) / 2;
-  term_rect.y = view->screen.y + (view->screen.height - term_rect.height) / 2;
+  get_min_terminal (terminal_font, border_width, &min_terminal_width, &min_terminal_height);
+  /* Check that border_width isn't too big */
+  if ((border_width > 3) && ((min_terminal_width >= screen_rect.width)
+                             || (min_terminal_height >= screen_rect.height)))
+    {
+      border_width = 3;
+      get_min_terminal (terminal_font, border_width, &min_terminal_width, &min_terminal_height);
+    }
+
+  signed x, y, w, h;
+  x = grub_fixed_sfs_multiply (screen_rect.width, view->xfrac) + view->x;
+  y = grub_fixed_sfs_multiply (screen_rect.height, view->yfrac) + view->y;
+  w = grub_fixed_sfs_multiply (screen_rect.width, view->wfrac) + view->w;
+  h = grub_fixed_sfs_multiply (screen_rect.height, view->hfrac) + view->h;
+
+  /* Sanity checks. */
+  if (w <= 0)
+    w = (signed) screen_rect.width * 7 / 10;
+  if (h <= 0)
+    h = (signed) screen_rect.height * 7 / 10;
+
+  if (w > (signed) screen_rect.width)
+    w = (signed) screen_rect.width;
+  if (h > (signed) screen_rect.height)
+    h = (signed) screen_rect.height;
+
+  if ((screen_rect.width <= min_terminal_width)
+      || (screen_rect.height <= min_terminal_height))
+    {
+      /* The terminal window is too small. Use all space, except a small border
+         to show the user, that it is a window. Then center the window. */
+      w = (signed) screen_rect.width - 6 * border_width;
+      h = (signed) screen_rect.height - 6 * border_width;
+      x = ((signed) screen_rect.width - w) / 2;
+      y = ((signed) screen_rect.height - h) / 2;
+    }
+  else if ((w < (signed) min_terminal_width)
+           || (h < (signed) min_terminal_height))
+    {
+      /* The terminal window is big enough. The desired width is satisfying.
+         Make sure, that screen dimensions aren't less than minimal values.
+         Then center the window. */
+      w = (signed) min_terminal_width;
+      h = (signed) min_terminal_height;
+      x = ((signed) screen_rect.width - w) / 2;
+      y = ((signed) screen_rect.height - h) / 2;
+    }
+
+  /* At this point w and h are satisfying. */
+  if (x + w > (signed) screen_rect.width)
+    x = (signed) screen_rect.width - w;
+  if (y + h > (signed) screen_rect.height)
+    y = (signed) screen_rect.height - h;
+
+  if (x < (signed) screen_rect.x)
+    x = (signed) screen_rect.x;
+  if (y < (signed) screen_rect.y)
+    y = (signed) screen_rect.y;
+
+  view->terminal_rect.x = x;
+  view->terminal_rect.width = w;
+  view->terminal_rect.y = y;
+  view->terminal_rect.height = h;
+  view->terminal_border = border_width;
 
   term_view = view;
 
   /* Note: currently there is no API for changing the gfxterm font
      on the fly, so whatever font the initially loaded theme specifies
      will be permanent.  */
-  grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, term_rect.x,
-			   term_rect.y,
-			   term_rect.width, term_rect.height,
+  grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, 
+                           x, y, w, h,
 			   view->double_repaint, terminal_font,
 			   border_width);
   grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box;
diff -Naur grub-2.01/include/grub/gfxmenu_view.h grub-new/include/grub/gfxmenu_view.h
--- grub-2.01/include/grub/gfxmenu_view.h	2013-02-25 16:54:27.000000000 +0400
+++ grub-new/include/grub/gfxmenu_view.h	2013-06-25 19:50:51.000000000 +0400
@@ -83,7 +83,18 @@
 struct grub_gfxmenu_view
 {
   grub_video_rect_t screen;
+  grub_video_rect_t terminal_rect;
 
+  signed x;
+  grub_fixed_signed_t xfrac;
+  signed y;
+  grub_fixed_signed_t yfrac;
+  signed w;
+  grub_fixed_signed_t wfrac;
+  signed h;
+  grub_fixed_signed_t hfrac;
+
+  int terminal_border;
   grub_font_t title_font;
   grub_font_t message_font;
   char *terminal_font_name;
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to