All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Testov <vladimir.testov@rosalab.ru>
To: grub-devel@gnu.org
Subject: [PATCH] [2/2] set terminal window in theme file
Date: Fri, 26 Apr 2013 17:06:17 +0400	[thread overview]
Message-ID: <2118171.2vjrbdaEK7@icedphoenix> (raw)

[-- Attachment #1: Type: text/plain, Size: 539 bytes --]


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

[-- Attachment #2: grub-terminal-move.patch --]
[-- Type: text/x-patch, Size: 10581 bytes --]

diff -Naur grub-new4/docs/grub.texi grub-new5/docs/grub.texi
--- grub-new4/docs/grub.texi	2013-04-26 11:58:20.041859276 +0400
+++ grub-new5/docs/grub.texi	2013-04-26 11:58:37.055800288 +0400
@@ -1901,6 +1901,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 terminal border's width.
+@item terminal-left @tab Specifies the terminal left coordinate.
+@item terminal-top @tab Specifies the termianl top coordinate.
+@item terminal-width @tab Specifies the terminal width.
+@item terminal-height @tab Specifies the terminal height.
 @end multitable
 
 
diff -Naur grub-new4/grub-core/gfxmenu/theme_loader.c grub-new5/grub-core/gfxmenu/theme_loader.c
--- grub-new4/grub-core/gfxmenu/theme_loader.c	2013-04-24 12:50:05.143117525 +0400
+++ grub-new5/grub-core/gfxmenu/theme_loader.c	2013-04-25 20:26:25.133801135 +0400
@@ -31,6 +31,9 @@
 #include <grub/gfxmenu_view.h>
 #include <grub/gui.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".
@@ -178,6 +181,56 @@
         if (err != GRUB_ERR_NONE)
           return err;
     }
+  else if (! grub_strcmp ("terminal-border", name))
+    {
+      view->terminal_border = grub_strtol (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-new4/grub-core/gfxmenu/view.c grub-new5/grub-core/gfxmenu/view.c
--- grub-new4/grub-core/gfxmenu/view.c	2013-04-24 12:34:44.999051941 +0400
+++ grub-new5/grub-core/gfxmenu/view.c	2013-04-26 16:00:37.923386069 +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
@@ -63,6 +62,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);
@@ -219,7 +231,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);
@@ -300,25 +312,36 @@
   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 *width, unsigned int *height)
 {
-  const int border_width = 3;
+  struct grub_font_glyph *glyph;
+  glyph = grub_font_get_glyph (terminal_font, 'M');
+  *width = (glyph? glyph->device_width : 8) * 80 + 2 * border_width;
+  *height = (grub_font_get_ascent (terminal_font)
+             + grub_font_get_descent (terminal_font)) * 20 + 2 * border_width;
+}
 
+static void
+init_terminal (grub_gfxmenu_view_t view)
+{
+  if (view->terminal_border < 0)
+    view->terminal_border = 0;
+  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 line_height;
 
   terminal_font = grub_font_get (view->terminal_font_name);
   if (!terminal_font)
@@ -327,36 +350,71 @@
       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
+  get_min_terminal (terminal_font, border_width, &line_width, &line_height);
+  /* Check that border_width isn't too big */
+  if ((border_width > 3) && ((line_width >= screen_rect.width)
+                             || (line_height >= screen_rect.height)))
     {
-      /* 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;
+      border_width = 3;
+      get_min_terminal (terminal_font, border_width, &line_width, &line_height);
     }
 
-  term_rect.height = view->screen.height * 7 / 10;
+  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;
 
-  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;
+  if (screen_rect.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: */
+    w = (signed) screen_rect.width - 6 * border_width;
+  else if (w < (signed) line_width)
+    /* The screen is big enough. The desired width is satisfying. */
+    /* Make sure, that we use at least the line_width: */
+    w = (signed) line_width;
+
+  /* The same procedure for height. */
+  if (screen_rect.height <= line_height)
+    h = (signed) screen_rect.height - 6 * border_width;
+  else if (h < (signed) line_height)
+    h = (signed) line_height;
+
+  /* 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-new4/include/grub/gfxmenu_view.h grub-new5/include/grub/gfxmenu_view.h
--- grub-new4/include/grub/gfxmenu_view.h	2013-04-24 12:29:40.203816750 +0400
+++ grub-new5/include/grub/gfxmenu_view.h	2013-04-25 20:24:58.936119052 +0400
@@ -89,7 +89,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;
   char *terminal_font_name;
   grub_video_rgba_color_t title_color;

             reply	other threads:[~2013-04-26 13:06 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-26 13:06 Vladimir Testov [this message]
2013-06-27 13:07 ` [PATCH] [2/2] set terminal window in theme file Vladimir Testov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2118171.2vjrbdaEK7@icedphoenix \
    --to=vladimir.testov@rosalab.ru \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.