|
40 | 40 |
|
41 | 41 | static void
|
42 | 42 | init_terminal (grub_gfxmenu_view_t view);
|
43 |
| -static grub_video_rect_t term_rect; |
44 | 43 | static grub_gfxmenu_view_t term_view;
|
45 | 44 |
|
46 | 45 | /* 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,
|
71 | 70 | view->screen.width = width;
|
72 | 71 | view->screen.height = height;
|
73 | 72 |
|
| 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 | + |
74 | 82 | default_font = grub_font_get ("Unknown Regular 16");
|
75 | 83 | default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
|
76 | 84 | default_bg_color = grub_video_rgba_color_rgb (255, 255, 255);
|
|
302 | 310 | grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
|
303 | 311 | const grub_video_rect_t *region)
|
304 | 312 | {
|
305 |
| - if (grub_video_have_common_points (&term_rect, region)) |
| 313 | + if (grub_video_have_common_points (&view->terminal_rect, region)) |
306 | 314 | grub_gfxterm_schedule_repaint ();
|
307 | 315 |
|
308 | 316 | grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
|
@@ -386,65 +394,133 @@ grub_gfxmenu_draw_terminal_box (void)
|
386 | 394 | term_box = term_view->terminal_box;
|
387 | 395 | if (!term_box)
|
388 | 396 | 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); |
392 | 400 |
|
393 | 401 | 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)); |
396 | 404 | }
|
397 | 405 |
|
398 | 406 | 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) |
400 | 411 | {
|
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 | +} |
402 | 419 |
|
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; |
404 | 425 |
|
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 | + } |
406 | 452 |
|
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; |
408 | 458 |
|
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) |
411 | 461 | {
|
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; |
414 | 478 | }
|
415 | 479 |
|
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; |
417 | 485 |
|
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; |
419 | 492 |
|
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) |
425 | 503 | {
|
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; |
431 | 506 | }
|
432 | 507 |
|
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); |
437 | 510 |
|
438 | 511 | term_view = view;
|
439 | 512 |
|
440 | 513 | /* Note: currently there is no API for changing the gfxterm font
|
441 | 514 | on the fly, so whatever font the initially loaded theme specifies
|
442 | 515 | 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); |
448 | 524 | grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box;
|
449 | 525 | }
|
450 | 526 |
|
|
0 commit comments