Skip to content

Commit 9d0631c

Browse files
author
Vladimir Testov
committedAug 8, 2013
* docs/grub.texi: Introduce terminal window position options:
terminal-left: terminal window's left position terminal-top: terminal window's top position terminal-width: terminal window's width terminal-height: terminal window's height * grub-core/gfxmenu/theme-loader.c: Likewise. * include/grub/gfxmenu_view.h: Likewise. * po/exlude.pot: Likewise. * grub-core/gfxmenu/view.c: Likewise. Also updated minimal window size. Also terminal_sanity_check function has been introduced.
1 parent 8fcfcf0 commit 9d0631c

File tree

7 files changed

+247
-60
lines changed

7 files changed

+247
-60
lines changed
 

‎ChangeLog

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
2013-08-07 Vladimir Testov <vladimir.testov@rosalab.ru>
2+
3+
* docs/grub.texi: Introduce terminal window position options:
4+
terminal-left: terminal window's left position
5+
terminal-top: terminal window's top position
6+
terminal-width: terminal window's width
7+
terminal-height: terminal window's height
8+
terminal-border: terminal window's border width
9+
* grub-core/gfxmenu/theme-loader.c: Likewise.
10+
* include/grub/gfxmenu_view.h: Likewise.
11+
* po/exlude.pot: Likewise.
12+
* grub-core/gfxmenu/view.c: Likewise.
13+
Also updated minimal window size.
14+
Also terminal_sanity_check function has been introduced.
15+
116
2013-08-02 Vladimir Serbinenko <phcoder@gmail.com>
217

318
* grub-core/tests/checksums.h: Update (1-pixel difference in marker

‎docs/grub.texi

+5
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,11 @@ In this example, name3 is assigned a color value.
19041904
@item desktop-image @tab Specifies the image to use as the background. It will be scaled to fit the screen size.
19051905
@item desktop-color @tab Specifies the color for the background if *desktop-image* is not specified.
19061906
@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.
1907+
@item terminal-border @tab Specifies the border width of the terminal window.
1908+
@item terminal-left @tab Specifies the left coordinate of the terminal window.
1909+
@item terminal-top @tab Specifies the top coordinate of the terminal window.
1910+
@item terminal-width @tab Specifies the width of the terminal window.
1911+
@item terminal-height @tab Specifies the height of the terminal window.
19071912
@end multitable
19081913

19091914

‎grub-core/gfxmenu/theme_loader.c

+70-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
#include <grub/gui.h>
3333
#include <grub/color.h>
3434

35+
static grub_err_t
36+
parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop);
37+
3538
/* Construct a new box widget using ABSPATTERN to find the pixmap files for
3639
it, storing the new box instance at *BOXPTR.
3740
PATTERN should be of the form: "(hd0,0)/somewhere/style*.png".
@@ -113,6 +116,24 @@ grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr,
113116
return grub_errno;
114117
}
115118

119+
static grub_err_t
120+
theme_get_unsigned_int_from_proportional (const char *value,
121+
unsigned absolute_value,
122+
unsigned int *parsed_value)
123+
{
124+
grub_err_t err;
125+
grub_fixed_signed_t frac;
126+
signed pixels;
127+
err = parse_proportional_spec (value, &pixels, &frac);
128+
if (err != GRUB_ERR_NONE)
129+
return err;
130+
int result = grub_fixed_sfs_multiply (absolute_value, frac) + pixels;
131+
if (result < 0)
132+
result = 0;
133+
*parsed_value = result;
134+
return GRUB_ERR_NONE;
135+
}
136+
116137
/* Set the specified property NAME on the view to the given string VALUE.
117138
The caller is responsible for the lifetimes of NAME and VALUE. */
118139
static grub_err_t
@@ -179,6 +200,52 @@ theme_set_string (grub_gfxmenu_view_t view,
179200
if (err != GRUB_ERR_NONE)
180201
return err;
181202
}
203+
else if (! grub_strcmp ("terminal-border", name))
204+
{
205+
view->terminal_border = grub_strtoul (value, 0, 10);
206+
if (grub_errno)
207+
return grub_errno;
208+
}
209+
else if (! grub_strcmp ("terminal-left", name))
210+
{
211+
unsigned int tmp;
212+
int err = theme_get_unsigned_int_from_proportional (value,
213+
view->screen.width,
214+
&tmp);
215+
if (err != GRUB_ERR_NONE)
216+
return err;
217+
view->terminal_rect.x = tmp;
218+
}
219+
else if (! grub_strcmp ("terminal-top", name))
220+
{
221+
unsigned int tmp;
222+
int err = theme_get_unsigned_int_from_proportional (value,
223+
view->screen.width,
224+
&tmp);
225+
if (err != GRUB_ERR_NONE)
226+
return err;
227+
view->terminal_rect.y = tmp;
228+
}
229+
else if (! grub_strcmp ("terminal-width", name))
230+
{
231+
unsigned int tmp;
232+
int err = theme_get_unsigned_int_from_proportional (value,
233+
view->screen.width,
234+
&tmp);
235+
if (err != GRUB_ERR_NONE)
236+
return err;
237+
view->terminal_rect.width = tmp;
238+
}
239+
else if (! grub_strcmp ("terminal-height", name))
240+
{
241+
unsigned int tmp;
242+
int err = theme_get_unsigned_int_from_proportional (value,
243+
view->screen.width,
244+
&tmp);
245+
if (err != GRUB_ERR_NONE)
246+
return err;
247+
view->terminal_rect.height = tmp;
248+
}
182249
else if (! grub_strcmp ("title-text", name))
183250
{
184251
grub_free (view->title_text);
@@ -363,10 +430,10 @@ read_expression (struct parsebuf *p)
363430
}
364431

365432
static grub_err_t
366-
parse_proportional_spec (char *value, signed *abs, grub_fixed_signed_t *prop)
433+
parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop)
367434
{
368435
signed num;
369-
char *ptr;
436+
const char *ptr;
370437
int sig = 0;
371438
*abs = 0;
372439
*prop = 0;
@@ -382,7 +449,7 @@ parse_proportional_spec (char *value, signed *abs, grub_fixed_signed_t *prop)
382449
ptr++;
383450
}
384451

385-
num = grub_strtoul (ptr, &ptr, 0);
452+
num = grub_strtoul (ptr, (char **) &ptr, 0);
386453
if (grub_errno)
387454
return grub_errno;
388455
if (sig)

‎grub-core/gfxmenu/view.c

+113-37
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040

4141
static void
4242
init_terminal (grub_gfxmenu_view_t view);
43-
static grub_video_rect_t term_rect;
4443
static grub_gfxmenu_view_t term_view;
4544

4645
/* Create a new view object, loading the theme specified by THEME_PATH and
@@ -71,6 +70,15 @@ grub_gfxmenu_view_new (const char *theme_path,
7170
view->screen.width = width;
7271
view->screen.height = height;
7372

73+
view->need_to_check_sanity = 1;
74+
view->terminal_border = 3;
75+
view->terminal_rect.width = view->screen.width * 7 / 10;
76+
view->terminal_rect.height = view->screen.height * 7 / 10;
77+
view->terminal_rect.x = view->screen.x + (view->screen.width
78+
- view->terminal_rect.width) / 2;
79+
view->terminal_rect.y = view->screen.y + (view->screen.height
80+
- view->terminal_rect.height) / 2;
81+
7482
default_font = grub_font_get ("Unknown Regular 16");
7583
default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
7684
default_bg_color = grub_video_rgba_color_rgb (255, 255, 255);
@@ -302,7 +310,7 @@ void
302310
grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
303311
const grub_video_rect_t *region)
304312
{
305-
if (grub_video_have_common_points (&term_rect, region))
313+
if (grub_video_have_common_points (&view->terminal_rect, region))
306314
grub_gfxterm_schedule_repaint ();
307315

308316
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
@@ -386,65 +394,133 @@ grub_gfxmenu_draw_terminal_box (void)
386394
term_box = term_view->terminal_box;
387395
if (!term_box)
388396
return;
389-
390-
term_box->set_content_size (term_box, term_rect.width,
391-
term_rect.height);
397+
398+
term_box->set_content_size (term_box, term_view->terminal_rect.width,
399+
term_view->terminal_rect.height);
392400

393401
term_box->draw (term_box,
394-
term_rect.x - term_box->get_left_pad (term_box),
395-
term_rect.y - term_box->get_top_pad (term_box));
402+
term_view->terminal_rect.x - term_box->get_left_pad (term_box),
403+
term_view->terminal_rect.y - term_box->get_top_pad (term_box));
396404
}
397405

398406
static void
399-
init_terminal (grub_gfxmenu_view_t view)
407+
get_min_terminal (grub_font_t terminal_font,
408+
unsigned int border_width,
409+
unsigned int *min_terminal_width,
410+
unsigned int *min_terminal_height)
400411
{
401-
const int border_width = 3;
412+
struct grub_font_glyph *glyph;
413+
glyph = grub_font_get_glyph (terminal_font, 'M');
414+
*min_terminal_width = (glyph? glyph->device_width : 8) * 80
415+
+ 2 * border_width;
416+
*min_terminal_height = grub_font_get_max_char_height (terminal_font) * 24
417+
+ 2 * border_width;
418+
}
402419

403-
grub_font_t terminal_font;
420+
static void
421+
terminal_sanity_check (grub_gfxmenu_view_t view)
422+
{
423+
if (!view->need_to_check_sanity)
424+
return;
404425

405-
unsigned int line_width;
426+
/* terminal_font was checked before in the init_terminal function. */
427+
grub_font_t terminal_font = grub_font_get (view->terminal_font_name);
428+
429+
/* Non-negative numbers below. */
430+
int scr_x = view->screen.x;
431+
int scr_y = view->screen.y;
432+
int scr_width = view->screen.width;
433+
int scr_height = view->screen.height;
434+
int term_x = view->terminal_rect.x;
435+
int term_y = view->terminal_rect.y;
436+
int term_width = view->terminal_rect.width;
437+
int term_height = view->terminal_rect.height;
438+
439+
/* Check that border_width isn't too big. */
440+
unsigned int border_width = view->terminal_border;
441+
unsigned int min_terminal_width;
442+
unsigned int min_terminal_height;
443+
get_min_terminal (terminal_font, border_width,
444+
&min_terminal_width, &min_terminal_height);
445+
if (border_width > 3 && ((int) min_terminal_width >= scr_width
446+
|| (int) min_terminal_height >= scr_height))
447+
{
448+
border_width = 3;
449+
get_min_terminal (terminal_font, border_width,
450+
&min_terminal_width, &min_terminal_height);
451+
}
406452

407-
struct grub_font_glyph *glyph;
453+
/* Sanity checks. */
454+
if (term_width > scr_width)
455+
term_width = scr_width;
456+
if (term_height > scr_height)
457+
term_height = scr_height;
408458

409-
terminal_font = grub_font_get (view->terminal_font_name);
410-
if (!terminal_font)
459+
if (scr_width <= (int) min_terminal_width
460+
|| scr_height <= (int) min_terminal_height)
411461
{
412-
grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
413-
return;
462+
/* The screen resulution is too low. Use all space, except a small border
463+
to show the user, that it is a window. Then center the window. */
464+
term_width = scr_width - 6 * border_width;
465+
term_height = scr_height - 6 * border_width;
466+
term_x = scr_x + (scr_width - term_width) / 2;
467+
term_y = scr_y + (scr_height - term_height) / 2;
468+
}
469+
else if (term_width < (int) min_terminal_width
470+
|| term_height < (int) min_terminal_height)
471+
{
472+
/* The screen resolution is big enough. Make sure, that terminal screen
473+
dimensions aren't less than minimal values. Then center the window. */
474+
term_width = (int) min_terminal_width;
475+
term_height = (int) min_terminal_height;
476+
term_x = scr_x + (scr_width - term_width) / 2;
477+
term_y = scr_y + (scr_height - term_height) / 2;
414478
}
415479

416-
glyph = grub_font_get_glyph (terminal_font, 'M');
480+
/* At this point w and h are satisfying. */
481+
if (term_x + term_width > scr_width)
482+
term_x = scr_width - term_width;
483+
if (term_y + term_height > scr_height)
484+
term_y = scr_height - term_height;
417485

418-
line_width = ((glyph ? glyph->device_width : 8) * 80 + 2 * border_width);
486+
/* Write down corrected data. */
487+
view->terminal_rect.x = (unsigned int) term_x;
488+
view->terminal_rect.y = (unsigned int) term_y;
489+
view->terminal_rect.width = (unsigned int) term_width;
490+
view->terminal_rect.height = (unsigned int) term_height;
491+
view->terminal_border = border_width;
419492

420-
if (view->screen.width <= line_width)
421-
/* The screen is too small. Use all space, except a small border
422-
to show the user, it is a window and not full screen: */
423-
term_rect.width = view->screen.width - 6 * border_width;
424-
else
493+
view->need_to_check_sanity = 0;
494+
}
495+
496+
static void
497+
init_terminal (grub_gfxmenu_view_t view)
498+
{
499+
grub_font_t terminal_font;
500+
501+
terminal_font = grub_font_get (view->terminal_font_name);
502+
if (!terminal_font)
425503
{
426-
/* The screen is big enough. Try 70% of the screen width: */
427-
term_rect.width = view->screen.width * 7 / 10;
428-
/* Make sure, that we use at least the line_width: */
429-
if ( term_rect.width < line_width )
430-
term_rect.width = line_width;
504+
grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
505+
return;
431506
}
432507

433-
term_rect.height = view->screen.height * 7 / 10;
434-
435-
term_rect.x = view->screen.x + (view->screen.width - term_rect.width) / 2;
436-
term_rect.y = view->screen.y + (view->screen.height - term_rect.height) / 2;
508+
/* Check that terminal window size and position are sane. */
509+
terminal_sanity_check (view);
437510

438511
term_view = view;
439512

440513
/* Note: currently there is no API for changing the gfxterm font
441514
on the fly, so whatever font the initially loaded theme specifies
442515
will be permanent. */
443-
grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, term_rect.x,
444-
term_rect.y,
445-
term_rect.width, term_rect.height,
446-
view->double_repaint, terminal_font,
447-
border_width);
516+
grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY,
517+
view->terminal_rect.x,
518+
view->terminal_rect.y,
519+
view->terminal_rect.width,
520+
view->terminal_rect.height,
521+
view->double_repaint,
522+
terminal_font,
523+
view->terminal_border);
448524
grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box;
449525
}
450526

‎grub-core/tests/checksums.h

+20-20
Large diffs are not rendered by default.

‎include/grub/gfxmenu_view.h

+4
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ struct grub_gfxmenu_view
8484
{
8585
grub_video_rect_t screen;
8686

87+
int need_to_check_sanity;
88+
grub_video_rect_t terminal_rect;
89+
int terminal_border;
90+
8791
grub_font_t title_font;
8892
grub_font_t message_font;
8993
char *terminal_font_name;

‎po/exclude.pot

+20
Original file line numberDiff line numberDiff line change
@@ -5072,3 +5072,23 @@ msgstr ""
50725072
#: grub-core/term/uboot/console.c:130
50735073
msgid "grub_term"
50745074
msgstr ""
5075+
5076+
#: grub-core/gfxmenu/theme_loader.c:203
5077+
msgid "terminal-border"
5078+
msgstr ""
5079+
5080+
#: grub-core/gfxmenu/theme_loader.c:209
5081+
msgid "terminal-left"
5082+
msgstr ""
5083+
5084+
#: grub-core/gfxmenu/theme_loader.c:219
5085+
msgid "terminal-top"
5086+
msgstr ""
5087+
5088+
#: grub-core/gfxmenu/theme_loader.c:229
5089+
msgid "terminal-width"
5090+
msgstr ""
5091+
5092+
#: grub-core/gfxmenu/theme_loader.c:239
5093+
msgid "terminal-height"
5094+
msgstr ""

0 commit comments

Comments
 (0)
Please sign in to comment.