Dynamically count the number of lines for the lower banner.

* grub-core/normal/menu_entry.c (per_term_screen): New member
	num_entries.
	(print_down): Use num_entries.
	(update_screen): Likewise.
	(grub_menu_entry_run): Set num_entries.
	* grub-core/normal/menu_text.c (menu_viewer_data): New member
	num_entries.
	(grub_print_message_indented): Move real part to ...
	(grub_print_message_indented_real): ... here. Additional argument
	dry_run.
	(draw_border): Additional argument num_entries.
	(print_message): Additional argument dry_run.
	(print_entries): Receive menu viewer data.
	(grub_menu_init_page): New argment num_entries.
	(menu_text_set_chosen_entry): Use num_entries.
	(grub_menu_try_text): Likewise.
	* grub-core/normal/term.c (print_ucs4_terminal): New argument dry_run.
	All users updated.
	(grub_ucs4_count_lines): New function.
	* include/grub/term.h (grub_term_cursor_x): Moved from here ..
	* grub-core/normal/menu_text.c (grub_term_cursor_x): ... to here.
	* include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): Removed.
	(grub_term_border_height): Likewise.
	(grub_term_num_entries): Likewise.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-04-10 13:56:23 +02:00
parent 277f955bf1
commit 8b8a81fa6a
6 changed files with 225 additions and 138 deletions

View file

@ -515,14 +515,16 @@ print_ucs4_terminal (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term,
struct term_state *state)
struct term_state *state,
int dry_run)
{
const grub_uint32_t *ptr;
grub_ssize_t startwidth = get_startwidth (term, margin_left);
grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left);
grub_ssize_t line_width = startwidth;
grub_ssize_t lastspacewidth = 0;
grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right);
const grub_uint32_t *line_start = str, *last_space = str - 1;
int lines = 0;
for (ptr = str; ptr < last_position; ptr++)
{
@ -560,50 +562,59 @@ print_ucs4_terminal (const grub_uint32_t * str,
else
lastspacewidth = line_width - last_width;
for (ptr2 = line_start; ptr2 < ptr; ptr2++)
{
/* Skip combining characters on non-UTF8 terminals. */
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
&& grub_unicode_get_comb_type (*ptr2)
!= GRUB_UNICODE_COMB_NONE)
continue;
putcode_real (*ptr2, term);
}
lines++;
grub_print_spaces (term, margin_right);
grub_putcode ('\n', term);
if (state && ++state->num_lines
>= (grub_ssize_t) grub_term_height (term) - 2)
if (!dry_run)
{
state->backlog_ucs4 = (ptr == last_space || *ptr == '\n')
? ptr + 1 : ptr;
state->backlog_len = last_position - state->backlog_ucs4;
return 1;
for (ptr2 = line_start; ptr2 < ptr; ptr2++)
{
/* Skip combining characters on non-UTF8 terminals. */
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
&& grub_unicode_get_comb_type (*ptr2)
!= GRUB_UNICODE_COMB_NONE)
continue;
putcode_real (*ptr2, term);
}
grub_print_spaces (term, margin_right);
grub_putcode ('\n', term);
if (state && ++state->num_lines
>= (grub_ssize_t) grub_term_height (term) - 2)
{
state->backlog_ucs4 = (ptr == last_space || *ptr == '\n')
? ptr + 1 : ptr;
state->backlog_len = last_position - state->backlog_ucs4;
return 1;
}
}
line_width -= lastspacewidth;
grub_print_spaces (term, margin_left);
if (!dry_run)
grub_print_spaces (term, margin_left);
if (ptr == last_space || *ptr == '\n')
ptr++;
line_start = ptr;
}
}
{
const grub_uint32_t *ptr2;
for (ptr2 = line_start; ptr2 < last_position; ptr2++)
{
/* Skip combining characters on non-UTF8 terminals. */
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
&& grub_unicode_get_comb_type (*ptr2)
!= GRUB_UNICODE_COMB_NONE)
continue;
putcode_real (*ptr2, term);
}
}
return 0;
if (line_start < last_position)
lines++;
if (!dry_run)
{
const grub_uint32_t *ptr2;
for (ptr2 = line_start; ptr2 < last_position; ptr2++)
{
/* Skip combining characters on non-UTF8 terminals. */
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
&& grub_unicode_get_comb_type (*ptr2)
!= GRUB_UNICODE_COMB_NONE)
continue;
putcode_real (*ptr2, term);
}
}
return dry_run ? lines : 0;
}
static struct term_state *
@ -672,7 +683,7 @@ print_backlog (struct grub_term_output *term,
int ret;
ret = print_ucs4_terminal (state->backlog_ucs4,
state->backlog_ucs4 + state->backlog_len,
margin_left, margin_right, term, state);
margin_left, margin_right, term, state, 0);
if (!ret)
{
grub_free (state->free);
@ -706,15 +717,19 @@ static int
print_ucs4_real (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term, int backlog)
struct grub_term_output *term, int backlog,
int dry_run)
{
struct term_state *state = NULL;
if (backlog)
state = find_term_state (term);
if (!dry_run)
{
if (backlog)
state = find_term_state (term);
if (((term->getxy (term) >> 8) & 0xff) < margin_left)
grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff));
if (((term->getxy (term) >> 8) & 0xff) < margin_left)
grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff));
}
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
@ -743,16 +758,30 @@ print_ucs4_real (const grub_uint32_t * str,
grub_print_error ();
return 0;
}
ret = put_glyphs_terminal (visual, visual_len, margin_left, margin_right,
term, state);
if (!ret)
grub_free (visual);
if (dry_run)
{
struct grub_unicode_glyph *vptr;
ret = 0;
for (vptr = visual; vptr < visual + visual_len; vptr++)
if (vptr->base == '\n')
ret++;
if (visual_len && visual[visual_len - 1].base != '\n')
ret++;
grub_free (visual);
}
else
state->free = visual;
{
ret = put_glyphs_terminal (visual, visual_len, margin_left,
margin_right, term, state);
if (!ret)
grub_free (visual);
else
state->free = visual;
}
return ret;
}
return print_ucs4_terminal (str, last_position, margin_left, margin_right,
term, state);
term, state, dry_run);
}
void
@ -762,9 +791,18 @@ grub_print_ucs4 (const grub_uint32_t * str,
struct grub_term_output *term)
{
print_ucs4_real (str, last_position, margin_left, margin_right,
term, 0);
term, 0, 0);
}
int
grub_ucs4_count_lines (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term)
{
return print_ucs4_real (str, last_position, margin_left, margin_right,
term, 0, 1);
}
void
grub_xputs_normal (const char *str)
@ -813,7 +851,7 @@ grub_xputs_normal (const char *str)
{
int cur;
cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0,
term, grub_more);
term, grub_more, 0);
if (cur)
backlog = 1;
}