merge mainline into backtrace
This commit is contained in:
commit
245f4582f9
871 changed files with 102908 additions and 16407 deletions
|
|
@ -34,7 +34,7 @@ struct grub_auth_user
|
|||
int authenticated;
|
||||
};
|
||||
|
||||
struct grub_auth_user *users = NULL;
|
||||
static struct grub_auth_user *users = NULL;
|
||||
|
||||
grub_err_t
|
||||
grub_auth_register_authentication (const char *user,
|
||||
|
|
@ -161,7 +161,7 @@ grub_username_get (char buf[], unsigned buf_size)
|
|||
|
||||
while (1)
|
||||
{
|
||||
key = GRUB_TERM_ASCII_CHAR (grub_getkey ());
|
||||
key = grub_getkey ();
|
||||
if (key == '\n' || key == '\r')
|
||||
break;
|
||||
|
||||
|
|
@ -201,7 +201,6 @@ grub_auth_check_authentication (const char *userlist)
|
|||
{
|
||||
char login[1024];
|
||||
struct grub_auth_user *cur = NULL;
|
||||
grub_err_t err;
|
||||
static unsigned long punishment_delay = 1;
|
||||
char entered[GRUB_AUTH_MAX_PASSLEN];
|
||||
struct grub_auth_user *user;
|
||||
|
|
@ -233,7 +232,7 @@ grub_auth_check_authentication (const char *userlist)
|
|||
if (!cur || ! cur->callback)
|
||||
goto access_denied;
|
||||
|
||||
err = cur->callback (login, entered, cur->arg);
|
||||
cur->callback (login, entered, cur->arg);
|
||||
if (is_authenticated (userlist))
|
||||
{
|
||||
punishment_delay = 1;
|
||||
|
|
@ -248,3 +247,27 @@ grub_auth_check_authentication (const char *userlist)
|
|||
|
||||
return GRUB_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_authenticate (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
return grub_auth_check_authentication ((argc >= 1) ? args[0] : "");
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
void
|
||||
grub_normal_auth_init (void)
|
||||
{
|
||||
cmd = grub_register_command ("authenticate",
|
||||
grub_cmd_authenticate,
|
||||
N_("[USERLIST]"), N_("Authenticate users"));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
grub_normal_auth_fini (void)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,16 +113,6 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
|
|||
count = 3;
|
||||
code = c & GRUB_UINT8_3_TRAILINGBITS;
|
||||
}
|
||||
else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS)
|
||||
{
|
||||
count = 4;
|
||||
code = c & GRUB_UINT8_2_TRAILINGBITS;
|
||||
}
|
||||
else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS)
|
||||
{
|
||||
count = 5;
|
||||
code = c & GRUB_UINT8_1_TRAILINGBIT;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -177,7 +167,7 @@ grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
|
|||
/* No surrogates in UCS-4... */
|
||||
*dest++ = '?';
|
||||
}
|
||||
else
|
||||
else if (code < 0x10000)
|
||||
{
|
||||
if (dest + 2 >= destend)
|
||||
break;
|
||||
|
|
@ -185,6 +175,15 @@ grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
|
|||
*dest++ = ((code >> 6) & 0x3F) | 0x80;
|
||||
*dest++ = (code & 0x3F) | 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dest + 3 >= destend)
|
||||
break;
|
||||
*dest++ = (code >> 18) | 0xF0;
|
||||
*dest++ = ((code >> 12) & 0x3F) | 0x80;
|
||||
*dest++ = ((code >> 6) & 0x3F) | 0x80;
|
||||
*dest++ = (code & 0x3F) | 0x80;
|
||||
}
|
||||
}
|
||||
*dest = 0;
|
||||
}
|
||||
|
|
@ -212,8 +211,10 @@ grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
|
|||
|| (code >= 0xD800 && code <= 0xDBFF))
|
||||
/* No surrogates in UCS-4... */
|
||||
cnt++;
|
||||
else
|
||||
else if (code < 0x10000)
|
||||
cnt += 3;
|
||||
else
|
||||
cnt += 4;
|
||||
}
|
||||
cnt++;
|
||||
|
||||
|
|
@ -273,16 +274,6 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize)
|
|||
count = 3;
|
||||
code = c & 0x07;
|
||||
}
|
||||
else if ((c & 0xfc) == 0xf8)
|
||||
{
|
||||
count = 4;
|
||||
code = c & 0x03;
|
||||
}
|
||||
else if ((c & 0xfe) == 0xfc)
|
||||
{
|
||||
count = 5;
|
||||
code = c & 0x01;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -375,16 +366,6 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
|
|||
count = 3;
|
||||
code = c & 0x07;
|
||||
}
|
||||
else if ((c & 0xfc) == 0xf8)
|
||||
{
|
||||
count = 4;
|
||||
code = c & 0x03;
|
||||
}
|
||||
else if ((c & 0xfe) == 0xfc)
|
||||
{
|
||||
count = 5;
|
||||
code = c & 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* invalid */
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ grub_cmdline_get (const char *prompt)
|
|||
grub_term_gotoxy (cl_term->term, cl_term->xpos, cl_term->ypos);
|
||||
}
|
||||
|
||||
void cl_set_pos_all ()
|
||||
void cl_set_pos_all (void)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < nterms; i++)
|
||||
|
|
@ -388,16 +388,18 @@ grub_cmdline_get (const char *prompt)
|
|||
|
||||
grub_refresh ();
|
||||
|
||||
while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
|
||||
while ((key = grub_getkey ()) != '\n' && key != '\r')
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 1: /* Ctrl-a */
|
||||
case GRUB_TERM_CTRL | 'a':
|
||||
case GRUB_TERM_KEY_HOME:
|
||||
lpos = 0;
|
||||
cl_set_pos_all ();
|
||||
break;
|
||||
|
||||
case 2: /* Ctrl-b */
|
||||
case GRUB_TERM_CTRL | 'b':
|
||||
case GRUB_TERM_KEY_LEFT:
|
||||
if (lpos > 0)
|
||||
{
|
||||
lpos--;
|
||||
|
|
@ -405,12 +407,14 @@ grub_cmdline_get (const char *prompt)
|
|||
}
|
||||
break;
|
||||
|
||||
case 5: /* Ctrl-e */
|
||||
case GRUB_TERM_CTRL | 'e':
|
||||
case GRUB_TERM_KEY_END:
|
||||
lpos = llen;
|
||||
cl_set_pos_all ();
|
||||
break;
|
||||
|
||||
case 6: /* Ctrl-f */
|
||||
case GRUB_TERM_CTRL | 'f':
|
||||
case GRUB_TERM_KEY_RIGHT:
|
||||
if (lpos < llen)
|
||||
{
|
||||
lpos++;
|
||||
|
|
@ -418,7 +422,8 @@ grub_cmdline_get (const char *prompt)
|
|||
}
|
||||
break;
|
||||
|
||||
case 9: /* Ctrl-i or TAB */
|
||||
case GRUB_TERM_CTRL | 'i':
|
||||
case '\t':
|
||||
{
|
||||
int restore;
|
||||
char *insertu8;
|
||||
|
|
@ -492,11 +497,10 @@ grub_cmdline_get (const char *prompt)
|
|||
}
|
||||
break;
|
||||
|
||||
case 11: /* Ctrl-k */
|
||||
case GRUB_TERM_CTRL | 'k':
|
||||
if (lpos < llen)
|
||||
{
|
||||
if (kill_buf)
|
||||
grub_free (kill_buf);
|
||||
grub_free (kill_buf);
|
||||
|
||||
kill_buf = grub_malloc ((llen - lpos + 1)
|
||||
* sizeof (grub_uint32_t));
|
||||
|
|
@ -516,7 +520,8 @@ grub_cmdline_get (const char *prompt)
|
|||
}
|
||||
break;
|
||||
|
||||
case 14: /* Ctrl-n */
|
||||
case GRUB_TERM_CTRL | 'n':
|
||||
case GRUB_TERM_KEY_DOWN:
|
||||
{
|
||||
grub_uint32_t *hist;
|
||||
|
||||
|
|
@ -534,7 +539,9 @@ grub_cmdline_get (const char *prompt)
|
|||
|
||||
break;
|
||||
}
|
||||
case 16: /* Ctrl-p */
|
||||
|
||||
case GRUB_TERM_KEY_UP:
|
||||
case GRUB_TERM_CTRL | 'p':
|
||||
{
|
||||
grub_uint32_t *hist;
|
||||
|
||||
|
|
@ -553,13 +560,12 @@ grub_cmdline_get (const char *prompt)
|
|||
}
|
||||
break;
|
||||
|
||||
case 21: /* Ctrl-u */
|
||||
case GRUB_TERM_CTRL | 'u':
|
||||
if (lpos > 0)
|
||||
{
|
||||
grub_size_t n = lpos;
|
||||
|
||||
if (kill_buf)
|
||||
grub_free (kill_buf);
|
||||
grub_free (kill_buf);
|
||||
|
||||
kill_buf = grub_malloc (n + 1);
|
||||
if (grub_errno)
|
||||
|
|
@ -579,7 +585,7 @@ grub_cmdline_get (const char *prompt)
|
|||
}
|
||||
break;
|
||||
|
||||
case 25: /* Ctrl-y */
|
||||
case GRUB_TERM_CTRL | 'y':
|
||||
if (kill_buf)
|
||||
cl_insert (kill_buf);
|
||||
break;
|
||||
|
|
@ -598,7 +604,8 @@ grub_cmdline_get (const char *prompt)
|
|||
break;
|
||||
/* fall through */
|
||||
|
||||
case 4: /* Ctrl-d */
|
||||
case GRUB_TERM_CTRL | 'd':
|
||||
case GRUB_TERM_KEY_DC:
|
||||
if (lpos < llen)
|
||||
cl_delete (1);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -100,15 +100,16 @@ static int
|
|||
iterate_partition (grub_disk_t disk, const grub_partition_t p)
|
||||
{
|
||||
const char *disk_name = disk->name;
|
||||
char *partition_name = grub_partition_get_name (p);
|
||||
char *name;
|
||||
int ret;
|
||||
char *part_name;
|
||||
|
||||
if (! partition_name)
|
||||
part_name = grub_partition_get_name (p);
|
||||
if (! part_name)
|
||||
return 1;
|
||||
|
||||
name = grub_xasprintf ("%s,%s", disk_name, partition_name);
|
||||
grub_free (partition_name);
|
||||
name = grub_xasprintf ("%s,%s", disk_name, part_name);
|
||||
grub_free (part_name);
|
||||
|
||||
if (! name)
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ struct menu_pointer
|
|||
struct menu_pointer *prev;
|
||||
};
|
||||
|
||||
struct menu_pointer initial_menu;
|
||||
struct menu_pointer *current_menu = &initial_menu;
|
||||
static struct menu_pointer initial_menu;
|
||||
static struct menu_pointer *current_menu = &initial_menu;
|
||||
|
||||
void
|
||||
grub_env_unset_menu (void)
|
||||
|
|
@ -52,8 +52,8 @@ grub_env_set_menu (grub_menu_t nmenu)
|
|||
current_menu->menu = nmenu;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_env_context_open (int export)
|
||||
static grub_err_t
|
||||
grub_env_new_context (int export_all)
|
||||
{
|
||||
struct grub_env_context *context;
|
||||
int i;
|
||||
|
|
@ -78,23 +78,36 @@ grub_env_context_open (int export)
|
|||
struct grub_env_var *var;
|
||||
|
||||
for (var = context->prev->vars[i]; var; var = var->next)
|
||||
{
|
||||
if (export && var->global)
|
||||
{
|
||||
if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_env_context_close ();
|
||||
return grub_errno;
|
||||
}
|
||||
grub_env_export (var->name);
|
||||
grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
|
||||
}
|
||||
}
|
||||
if (var->global || export_all)
|
||||
{
|
||||
if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_env_context_close ();
|
||||
return grub_errno;
|
||||
}
|
||||
grub_env_export (var->name);
|
||||
grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
|
||||
}
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_env_context_open (void)
|
||||
{
|
||||
return grub_env_new_context (0);
|
||||
}
|
||||
|
||||
int grub_extractor_level = 0;
|
||||
|
||||
grub_err_t
|
||||
grub_env_extractor_open (int source)
|
||||
{
|
||||
grub_extractor_level++;
|
||||
return grub_env_new_context (source);
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_env_context_close (void)
|
||||
{
|
||||
|
|
@ -133,23 +146,34 @@ grub_env_context_close (void)
|
|||
}
|
||||
|
||||
grub_err_t
|
||||
grub_env_export (const char *name)
|
||||
grub_env_extractor_close (int source)
|
||||
{
|
||||
struct grub_env_var *var;
|
||||
grub_menu_t menu = NULL;
|
||||
grub_menu_entry_t *last;
|
||||
grub_err_t err;
|
||||
|
||||
var = grub_env_find (name);
|
||||
if (! var)
|
||||
if (source)
|
||||
{
|
||||
grub_err_t err;
|
||||
|
||||
err = grub_env_set (name, "");
|
||||
if (err)
|
||||
return err;
|
||||
var = grub_env_find (name);
|
||||
}
|
||||
var->global = 1;
|
||||
menu = grub_env_get_menu ();
|
||||
grub_env_unset_menu ();
|
||||
}
|
||||
err = grub_env_context_close ();
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
if (source)
|
||||
{
|
||||
grub_menu_t menu2;
|
||||
menu2 = grub_env_get_menu ();
|
||||
|
||||
last = &menu2->entry_list;
|
||||
while (*last)
|
||||
last = &(*last)->next;
|
||||
|
||||
*last = menu->entry_list;
|
||||
menu2->size += menu->size;
|
||||
}
|
||||
|
||||
grub_extractor_level--;
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_command_t export_cmd;
|
||||
|
|
@ -173,9 +197,6 @@ grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
|
|||
void
|
||||
grub_context_init (void)
|
||||
{
|
||||
grub_env_export ("root");
|
||||
grub_env_export ("prefix");
|
||||
|
||||
export_cmd = grub_register_command ("export", grub_cmd_export,
|
||||
N_("ENVVAR [ENVVAR] ..."),
|
||||
N_("Export variables."));
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ struct load_spec
|
|||
char *modname;
|
||||
};
|
||||
|
||||
struct load_spec *crypto_specs = NULL;
|
||||
static struct load_spec *crypto_specs = NULL;
|
||||
|
||||
static void
|
||||
grub_crypto_autoload (const char *name)
|
||||
|
|
|
|||
|
|
@ -18,16 +18,17 @@
|
|||
*/
|
||||
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
static char *grub_weekday_names[] =
|
||||
static const char *grub_weekday_names[] =
|
||||
{
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
N_("Sunday"),
|
||||
N_("Monday"),
|
||||
N_("Tuesday"),
|
||||
N_("Wednesday"),
|
||||
N_("Thursday"),
|
||||
N_("Friday"),
|
||||
N_("Saturday"),
|
||||
};
|
||||
|
||||
int
|
||||
|
|
@ -42,10 +43,10 @@ grub_get_weekday (struct grub_datetime *datetime)
|
|||
return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7;
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
grub_get_weekday_name (struct grub_datetime *datetime)
|
||||
{
|
||||
return grub_weekday_names[grub_get_weekday (datetime)];
|
||||
return _ (grub_weekday_names[grub_get_weekday (datetime)]);
|
||||
}
|
||||
|
||||
#define SECPERMIN 60
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#include <grub/charset.h>
|
||||
#include <grub/script_sh.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define GRUB_DEFAULT_HISTORY_SIZE 50
|
||||
|
||||
static int nested_level = 0;
|
||||
|
|
@ -123,8 +125,8 @@ grub_file_getline (grub_file_t file)
|
|||
return cmdline;
|
||||
}
|
||||
|
||||
static void
|
||||
free_menu (grub_menu_t menu)
|
||||
void
|
||||
grub_normal_free_menu (grub_menu_t menu)
|
||||
{
|
||||
grub_menu_entry_t entry = menu->entry_list;
|
||||
|
||||
|
|
@ -272,7 +274,6 @@ grub_normal_execute (const char *config, int nested, int batch)
|
|||
prefix = grub_env_get ("prefix");
|
||||
read_lists (prefix);
|
||||
grub_register_variable_hook ("prefix", NULL, read_lists_hook);
|
||||
grub_command_execute ("parser.grub", 0, 0);
|
||||
}
|
||||
|
||||
if (config)
|
||||
|
|
@ -287,9 +288,9 @@ grub_normal_execute (const char *config, int nested, int batch)
|
|||
{
|
||||
if (menu && menu->size)
|
||||
{
|
||||
grub_show_menu (menu, nested);
|
||||
grub_show_menu (menu, nested, 0);
|
||||
if (nested)
|
||||
free_menu (menu);
|
||||
grub_normal_free_menu (menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -471,12 +472,18 @@ grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
|
|||
static grub_command_t cmd_clear;
|
||||
|
||||
static void (*grub_xputs_saved) (const char *str);
|
||||
static const char *features[] = {
|
||||
"feature_chainloader_bpb", "feature_ntldr"
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(normal)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* Previously many modules depended on gzio. Be nice to user and load it. */
|
||||
grub_dl_load ("gzio");
|
||||
|
||||
grub_normal_auth_init ();
|
||||
grub_context_init ();
|
||||
grub_script_init ();
|
||||
grub_menu_init ();
|
||||
|
|
@ -495,6 +502,7 @@ GRUB_MOD_INIT(normal)
|
|||
grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
|
||||
|
||||
grub_register_variable_hook ("pager", 0, grub_env_write_pager);
|
||||
grub_env_export ("pager");
|
||||
|
||||
/* Register a command "normal" for the rescue mode. */
|
||||
grub_register_command ("normal", grub_cmd_normal,
|
||||
|
|
@ -513,6 +521,12 @@ GRUB_MOD_INIT(normal)
|
|||
/* Set default color names. */
|
||||
grub_env_set ("color_normal", "white/black");
|
||||
grub_env_set ("color_highlight", "black/white");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (features); i++)
|
||||
{
|
||||
grub_env_set (features[i], "y");
|
||||
grub_env_export (features[i]);
|
||||
}
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(normal)
|
||||
|
|
@ -520,6 +534,7 @@ GRUB_MOD_FINI(normal)
|
|||
grub_context_fini ();
|
||||
grub_script_fini ();
|
||||
grub_menu_fini ();
|
||||
grub_normal_auth_fini ();
|
||||
|
||||
grub_xputs = grub_xputs_saved;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#include <grub/i18n.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
/* Time to delay after displaying an error message about a default/fallback
|
||||
entry failing to boot. */
|
||||
|
|
@ -77,7 +79,7 @@ grub_menu_get_entry (grub_menu_t menu, int no)
|
|||
int
|
||||
grub_menu_get_timeout (void)
|
||||
{
|
||||
char *val;
|
||||
const char *val;
|
||||
int timeout;
|
||||
|
||||
val = grub_env_get ("timeout");
|
||||
|
|
@ -122,7 +124,7 @@ grub_menu_set_timeout (int timeout)
|
|||
static int
|
||||
get_and_remove_first_entry_number (const char *name)
|
||||
{
|
||||
char *val;
|
||||
const char *val;
|
||||
char *tail;
|
||||
int entry;
|
||||
|
||||
|
|
@ -154,10 +156,15 @@ get_and_remove_first_entry_number (const char *name)
|
|||
}
|
||||
|
||||
/* Run a menu entry. */
|
||||
void
|
||||
grub_menu_execute_entry(grub_menu_entry_t entry)
|
||||
static void
|
||||
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
|
||||
{
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
int errs_before;
|
||||
grub_menu_t menu = NULL;
|
||||
char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
|
||||
const char *ptr, *chosen, *def;
|
||||
grub_size_t sz = 0;
|
||||
|
||||
if (entry->restricted)
|
||||
err = grub_auth_check_authentication (entry->users);
|
||||
|
|
@ -169,21 +176,116 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
|
|||
return;
|
||||
}
|
||||
|
||||
grub_env_set ("chosen", entry->title);
|
||||
errs_before = grub_err_printed_errors;
|
||||
|
||||
chosen = grub_env_get ("chosen");
|
||||
def = grub_env_get ("default");
|
||||
|
||||
if (entry->submenu)
|
||||
{
|
||||
grub_env_context_open ();
|
||||
menu = grub_zalloc (sizeof (*menu));
|
||||
if (! menu)
|
||||
return;
|
||||
grub_env_set_menu (menu);
|
||||
if (auto_boot)
|
||||
grub_env_set ("timeout", "0");
|
||||
}
|
||||
|
||||
for (ptr = entry->title; *ptr; ptr++)
|
||||
sz += (*ptr == '>') ? 2 : 1;
|
||||
if (chosen)
|
||||
{
|
||||
oldchosen = grub_strdup (chosen);
|
||||
if (!oldchosen)
|
||||
grub_print_error ();
|
||||
}
|
||||
if (def)
|
||||
{
|
||||
olddefault = grub_strdup (def);
|
||||
if (!olddefault)
|
||||
grub_print_error ();
|
||||
}
|
||||
sz++;
|
||||
if (chosen)
|
||||
sz += grub_strlen (chosen);
|
||||
sz++;
|
||||
buf = grub_malloc (sz);
|
||||
if (!buf)
|
||||
grub_print_error ();
|
||||
else
|
||||
{
|
||||
optr = buf;
|
||||
if (chosen)
|
||||
{
|
||||
optr = grub_stpcpy (optr, chosen);
|
||||
*optr++ = '>';
|
||||
}
|
||||
for (ptr = entry->title; *ptr; ptr++)
|
||||
{
|
||||
if (*ptr == '>')
|
||||
*optr++ = '>';
|
||||
*optr++ = *ptr;
|
||||
}
|
||||
*optr = 0;
|
||||
grub_env_set ("chosen", buf);
|
||||
grub_env_export ("chosen");
|
||||
grub_free (buf);
|
||||
}
|
||||
|
||||
for (ptr = def; ptr && *ptr; ptr++)
|
||||
{
|
||||
if (ptr[0] == '>' && ptr[1] == '>')
|
||||
{
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
if (ptr[0] == '>')
|
||||
break;
|
||||
}
|
||||
|
||||
if (ptr && ptr[0] && ptr[1])
|
||||
grub_env_set ("default", ptr + 1);
|
||||
else
|
||||
grub_env_unset ("default");
|
||||
|
||||
grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
grub_wait_after_message ();
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
|
||||
/* Implicit execution of boot, only if something is loaded. */
|
||||
grub_command_execute ("boot", 0, 0);
|
||||
|
||||
if (entry->submenu)
|
||||
{
|
||||
if (menu && menu->size)
|
||||
{
|
||||
grub_show_menu (menu, 1, auto_boot);
|
||||
grub_normal_free_menu (menu);
|
||||
}
|
||||
grub_env_context_close ();
|
||||
}
|
||||
if (oldchosen)
|
||||
grub_env_set ("chosen", oldchosen);
|
||||
else
|
||||
grub_env_unset ("chosen");
|
||||
if (olddefault)
|
||||
grub_env_set ("default", olddefault);
|
||||
else
|
||||
grub_env_unset ("default");
|
||||
grub_env_unset ("timeout");
|
||||
}
|
||||
|
||||
/* Execute ENTRY from the menu MENU, falling back to entries specified
|
||||
in the environment variable "fallback" if it fails. CALLBACK is a
|
||||
pointer to a struct of function pointers which are used to allow the
|
||||
caller provide feedback to the user. */
|
||||
void
|
||||
static void
|
||||
grub_menu_execute_with_fallback (grub_menu_t menu,
|
||||
grub_menu_entry_t entry,
|
||||
int autobooted,
|
||||
grub_menu_execute_callback_t callback,
|
||||
void *callback_data)
|
||||
{
|
||||
|
|
@ -191,7 +293,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
|
|||
|
||||
callback->notify_booting (entry, callback_data);
|
||||
|
||||
grub_menu_execute_entry (entry);
|
||||
grub_menu_execute_entry (entry, 1);
|
||||
|
||||
/* Deal with fallback entries. */
|
||||
while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
|
||||
|
|
@ -202,14 +304,15 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
|
|||
|
||||
entry = grub_menu_get_entry (menu, fallback_entry);
|
||||
callback->notify_fallback (entry, callback_data);
|
||||
grub_menu_execute_entry (entry);
|
||||
grub_menu_execute_entry (entry, 1);
|
||||
/* If the function call to execute the entry returns at all, then this is
|
||||
taken to indicate a boot failure. For menu entries that do something
|
||||
other than actually boot an operating system, this could assume
|
||||
incorrectly that something failed. */
|
||||
}
|
||||
|
||||
callback->notify_failure (callback_data);
|
||||
if (!autobooted)
|
||||
callback->notify_failure (callback_data);
|
||||
}
|
||||
|
||||
static struct grub_menu_viewer *viewers;
|
||||
|
|
@ -247,18 +350,44 @@ static void
|
|||
menu_init (int entry, grub_menu_t menu, int nested)
|
||||
{
|
||||
struct grub_term_output *term;
|
||||
int gfxmenu = 0;
|
||||
|
||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||
if (grub_strcmp (term->name, "gfxterm") == 0)
|
||||
{
|
||||
if (grub_env_get ("theme"))
|
||||
{
|
||||
if (!grub_gfxmenu_try_hook)
|
||||
{
|
||||
grub_dl_load ("gfxmenu");
|
||||
grub_print_error ();
|
||||
}
|
||||
if (grub_gfxmenu_try_hook)
|
||||
{
|
||||
grub_err_t err;
|
||||
err = grub_gfxmenu_try_hook (entry, menu, nested);
|
||||
if(!err)
|
||||
{
|
||||
gfxmenu = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
grub_error (GRUB_ERR_BAD_MODULE, "no gfxmenu found");
|
||||
grub_print_error ();
|
||||
grub_wait_after_message ();
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
grub_gfxterm_fullscreen ();
|
||||
break;
|
||||
}
|
||||
|
||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||
{
|
||||
grub_err_t err;
|
||||
|
||||
if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0)
|
||||
{
|
||||
err = grub_gfxmenu_try_hook (entry, menu, nested);
|
||||
if(!err)
|
||||
continue;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (grub_strcmp (term->name, "gfxterm") == 0 && gfxmenu)
|
||||
break;
|
||||
|
||||
err = grub_menu_try_text (term, entry, menu, nested);
|
||||
if(!err)
|
||||
|
|
@ -283,11 +412,35 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer)
|
|||
viewers = viewer;
|
||||
}
|
||||
|
||||
static int
|
||||
menuentry_eq (const char *title, const char *spec)
|
||||
{
|
||||
const char *ptr1, *ptr2;
|
||||
ptr1 = title;
|
||||
ptr2 = spec;
|
||||
while (1)
|
||||
{
|
||||
if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0)
|
||||
return 1;
|
||||
if (*ptr2 == '>' && ptr2[1] != '>')
|
||||
return 0;
|
||||
if (*ptr2 == '>')
|
||||
ptr2++;
|
||||
if (*ptr1 != *ptr2)
|
||||
return 0;
|
||||
if (*ptr1 == 0)
|
||||
return 1;
|
||||
ptr1++;
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get the entry number from the variable NAME. */
|
||||
static int
|
||||
get_entry_number (grub_menu_t menu, const char *name)
|
||||
{
|
||||
char *val;
|
||||
const char *val;
|
||||
int entry;
|
||||
|
||||
val = grub_env_get (name);
|
||||
|
|
@ -308,7 +461,7 @@ get_entry_number (grub_menu_t menu, const char *name)
|
|||
|
||||
for (i = 0; e; i++)
|
||||
{
|
||||
if (grub_strcmp (e->title, val) == 0)
|
||||
if (menuentry_eq (e->title, val))
|
||||
{
|
||||
entry = i;
|
||||
break;
|
||||
|
|
@ -407,7 +560,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
|
|||
|
||||
if (grub_checkkey () >= 0 || timeout < 0)
|
||||
{
|
||||
c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
|
||||
c = grub_getkey ();
|
||||
|
||||
if (timeout >= 0)
|
||||
{
|
||||
|
|
@ -418,31 +571,36 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
|
|||
|
||||
switch (c)
|
||||
{
|
||||
case GRUB_TERM_HOME:
|
||||
case GRUB_TERM_KEY_HOME:
|
||||
case GRUB_TERM_CTRL | 'a':
|
||||
current_entry = 0;
|
||||
menu_set_chosen_entry (current_entry);
|
||||
break;
|
||||
|
||||
case GRUB_TERM_END:
|
||||
case GRUB_TERM_KEY_END:
|
||||
case GRUB_TERM_CTRL | 'e':
|
||||
current_entry = menu->size - 1;
|
||||
menu_set_chosen_entry (current_entry);
|
||||
break;
|
||||
|
||||
case GRUB_TERM_UP:
|
||||
case GRUB_TERM_KEY_UP:
|
||||
case GRUB_TERM_CTRL | 'p':
|
||||
case '^':
|
||||
if (current_entry > 0)
|
||||
current_entry--;
|
||||
menu_set_chosen_entry (current_entry);
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DOWN:
|
||||
case GRUB_TERM_CTRL | 'n':
|
||||
case GRUB_TERM_KEY_DOWN:
|
||||
case 'v':
|
||||
if (current_entry < menu->size - 1)
|
||||
current_entry++;
|
||||
menu_set_chosen_entry (current_entry);
|
||||
break;
|
||||
|
||||
case GRUB_TERM_PPAGE:
|
||||
case GRUB_TERM_CTRL | 'g':
|
||||
case GRUB_TERM_KEY_PPAGE:
|
||||
if (current_entry < GRUB_MENU_PAGE_SIZE)
|
||||
current_entry = 0;
|
||||
else
|
||||
|
|
@ -450,7 +608,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
|
|||
menu_set_chosen_entry (current_entry);
|
||||
break;
|
||||
|
||||
case GRUB_TERM_NPAGE:
|
||||
case GRUB_TERM_CTRL | 'c':
|
||||
case GRUB_TERM_KEY_NPAGE:
|
||||
if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size)
|
||||
current_entry += GRUB_MENU_PAGE_SIZE;
|
||||
else
|
||||
|
|
@ -460,7 +619,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
|
|||
|
||||
case '\n':
|
||||
case '\r':
|
||||
case 6:
|
||||
case GRUB_TERM_KEY_RIGHT:
|
||||
case GRUB_TERM_CTRL | 'f':
|
||||
menu_fini ();
|
||||
*auto_boot = 0;
|
||||
return current_entry;
|
||||
|
|
@ -557,7 +717,7 @@ static struct grub_menu_execute_callback execution_callback =
|
|||
};
|
||||
|
||||
static grub_err_t
|
||||
show_menu (grub_menu_t menu, int nested)
|
||||
show_menu (grub_menu_t menu, int nested, int autobooted)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
|
@ -576,33 +736,26 @@ show_menu (grub_menu_t menu, int nested)
|
|||
grub_cls ();
|
||||
|
||||
if (auto_boot)
|
||||
{
|
||||
grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
|
||||
}
|
||||
grub_menu_execute_with_fallback (menu, e, autobooted,
|
||||
&execution_callback, 0);
|
||||
else
|
||||
{
|
||||
int chars_before = grub_normal_get_char_counter ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
grub_menu_execute_entry (e);
|
||||
grub_print_error ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
if (chars_before != grub_normal_get_char_counter ())
|
||||
grub_wait_after_message ();
|
||||
}
|
||||
grub_menu_execute_entry (e, 0);
|
||||
if (autobooted)
|
||||
break;
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_show_menu (grub_menu_t menu, int nested)
|
||||
grub_show_menu (grub_menu_t menu, int nested, int autoboot)
|
||||
{
|
||||
grub_err_t err1, err2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
err1 = show_menu (menu, nested);
|
||||
err1 = show_menu (menu, nested, autoboot);
|
||||
autoboot = 0;
|
||||
grub_print_error ();
|
||||
|
||||
if (grub_normal_exit_level)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ struct per_term_screen
|
|||
int x;
|
||||
/* The Y coordinate. */
|
||||
int y;
|
||||
/* Number of entries. */
|
||||
int num_entries;
|
||||
};
|
||||
|
||||
struct screen
|
||||
|
|
@ -71,6 +73,8 @@ struct screen
|
|||
/* The flag of a completion window. */
|
||||
int completion_shown;
|
||||
|
||||
int submenu;
|
||||
|
||||
struct per_term_screen *terms;
|
||||
unsigned nterms;
|
||||
};
|
||||
|
|
@ -85,7 +89,7 @@ init_line (struct line *linep)
|
|||
{
|
||||
linep->len = 0;
|
||||
linep->max_len = 80; /* XXX */
|
||||
linep->buf = grub_malloc (linep->max_len);
|
||||
linep->buf = grub_malloc (linep->max_len + 1);
|
||||
if (! linep->buf)
|
||||
return 0;
|
||||
|
||||
|
|
@ -170,7 +174,7 @@ static void
|
|||
print_up (int flag, struct per_term_screen *term_screen)
|
||||
{
|
||||
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
|
||||
+ grub_term_entry_width (term_screen->term),
|
||||
+ grub_term_border_width (term_screen->term),
|
||||
GRUB_TERM_FIRST_ENTRY_Y);
|
||||
|
||||
if (flag)
|
||||
|
|
@ -186,7 +190,7 @@ print_down (int flag, struct per_term_screen *term_screen)
|
|||
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
|
||||
+ grub_term_border_width (term_screen->term),
|
||||
GRUB_TERM_TOP_BORDER_Y
|
||||
+ grub_term_num_entries (term_screen->term));
|
||||
+ term_screen->num_entries);
|
||||
|
||||
if (flag)
|
||||
grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term);
|
||||
|
|
@ -207,13 +211,12 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
|||
struct line *linep;
|
||||
|
||||
/* Check if scrolling is necessary. */
|
||||
if (term_screen->y < 0 || term_screen->y
|
||||
>= grub_term_num_entries (term_screen->term))
|
||||
if (term_screen->y < 0 || term_screen->y >= term_screen->num_entries)
|
||||
{
|
||||
if (term_screen->y < 0)
|
||||
term_screen->y = 0;
|
||||
else
|
||||
term_screen->y = grub_term_num_entries (term_screen->term) - 1;
|
||||
term_screen->y = term_screen->num_entries - 1;
|
||||
|
||||
region_start = 0;
|
||||
region_column = 0;
|
||||
|
|
@ -249,7 +252,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
|||
|
||||
for (column = 0;
|
||||
column <= linep->len
|
||||
&& y < grub_term_num_entries (term_screen->term);
|
||||
&& y < term_screen->num_entries;
|
||||
column += grub_term_entry_width (term_screen->term), y++)
|
||||
{
|
||||
if (y < 0)
|
||||
|
|
@ -270,7 +273,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
|||
print_line (linep, column, 0, y, term_screen);
|
||||
}
|
||||
|
||||
if (y == grub_term_num_entries (term_screen->term))
|
||||
if (y == term_screen->num_entries)
|
||||
{
|
||||
if (column <= linep->len || i + 1 < screen->num_lines)
|
||||
down_flag = 1;
|
||||
|
|
@ -280,11 +283,11 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
|||
i++;
|
||||
|
||||
if (mode == ALL_LINES && i == screen->num_lines)
|
||||
for (; y < grub_term_num_entries (term_screen->term); y++)
|
||||
for (; y < term_screen->num_entries; y++)
|
||||
print_empty_line (y, term_screen);
|
||||
|
||||
}
|
||||
while (y < grub_term_num_entries (term_screen->term));
|
||||
while (y < term_screen->num_entries);
|
||||
|
||||
/* Draw up and down arrows. */
|
||||
if (up)
|
||||
|
|
@ -496,6 +499,8 @@ make_screen (grub_menu_entry_t entry)
|
|||
if (! screen)
|
||||
return 0;
|
||||
|
||||
screen->submenu = entry->submenu;
|
||||
|
||||
screen->num_lines = 1;
|
||||
screen->lines = grub_malloc (sizeof (struct line));
|
||||
if (! screen->lines)
|
||||
|
|
@ -1159,54 +1164,76 @@ clear_completions_all (struct screen *screen)
|
|||
static int
|
||||
run (struct screen *screen)
|
||||
{
|
||||
int currline = 0;
|
||||
char *nextline;
|
||||
char *script;
|
||||
int errs_before;
|
||||
grub_menu_t menu = NULL;
|
||||
char *dummy[1] = { NULL };
|
||||
|
||||
auto grub_err_t editor_getline (char **line, int cont);
|
||||
grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
|
||||
{
|
||||
struct line *linep = screen->lines + currline;
|
||||
char *p;
|
||||
auto char * editor_getsource (void);
|
||||
char * editor_getsource (void)
|
||||
{
|
||||
int i;
|
||||
int size = 0;
|
||||
char *source;
|
||||
|
||||
if (currline > screen->num_lines)
|
||||
{
|
||||
*line = 0;
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < screen->num_lines; i++)
|
||||
size += screen->lines[i].len + 1;
|
||||
|
||||
/* Trim down space characters. */
|
||||
for (p = linep->buf + linep->len - 1;
|
||||
p >= linep->buf && grub_isspace (*p);
|
||||
p--)
|
||||
;
|
||||
*++p = '\0';
|
||||
source = grub_malloc (size + 1);
|
||||
if (! source)
|
||||
return NULL;
|
||||
|
||||
linep->len = p - linep->buf;
|
||||
for (p = linep->buf; grub_isspace (*p); p++)
|
||||
;
|
||||
*line = grub_strdup (p);
|
||||
currline++;
|
||||
return 0;
|
||||
}
|
||||
size = 0;
|
||||
for (i = 0; i < screen->num_lines; i++)
|
||||
{
|
||||
grub_memcpy (source + size, screen->lines[i].buf, screen->lines[i].len);
|
||||
size += screen->lines[i].len;
|
||||
source[size++] = '\n';
|
||||
}
|
||||
source[size] = '\0';
|
||||
return source;
|
||||
}
|
||||
|
||||
grub_cls ();
|
||||
grub_printf (" ");
|
||||
grub_printf_ (N_("Booting a command list"));
|
||||
grub_printf ("\n\n");
|
||||
|
||||
errs_before = grub_err_printed_errors;
|
||||
|
||||
if (screen->submenu)
|
||||
{
|
||||
grub_env_context_open ();
|
||||
menu = grub_zalloc (sizeof (*menu));
|
||||
if (! menu)
|
||||
return 0;
|
||||
grub_env_set_menu (menu);
|
||||
}
|
||||
|
||||
/* Execute the script, line for line. */
|
||||
while (currline < screen->num_lines)
|
||||
{
|
||||
editor_getline (&nextline, 0);
|
||||
if (grub_normal_parse_line (nextline, editor_getline))
|
||||
break;
|
||||
}
|
||||
script = editor_getsource ();
|
||||
if (! script)
|
||||
return 0;
|
||||
grub_script_execute_sourcecode (script, 0, dummy);
|
||||
grub_free (script);
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
grub_wait_after_message ();
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
|
||||
/* Implicit execution of boot, only if something is loaded. */
|
||||
grub_command_execute ("boot", 0, 0);
|
||||
|
||||
if (screen->submenu)
|
||||
{
|
||||
if (menu && menu->size)
|
||||
{
|
||||
grub_show_menu (menu, 1, 0);
|
||||
grub_normal_free_menu (menu);
|
||||
}
|
||||
grub_env_context_close ();
|
||||
}
|
||||
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_print_error ();
|
||||
|
|
@ -1264,7 +1291,8 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
|||
}
|
||||
/* Draw the screen. */
|
||||
for (i = 0; i < screen->nterms; i++)
|
||||
grub_menu_init_page (0, 1, screen->terms[i].term);
|
||||
grub_menu_init_page (0, 1, &screen->terms[i].num_entries,
|
||||
screen->terms[i].term);
|
||||
update_screen_all (screen, 0, 0, 1, 1, ALL_LINES);
|
||||
for (i = 0; i < screen->nterms; i++)
|
||||
grub_term_setcursor (screen->terms[i].term, 1);
|
||||
|
|
@ -1272,7 +1300,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
|||
|
||||
while (1)
|
||||
{
|
||||
int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
|
||||
int c = grub_getkey ();
|
||||
|
||||
if (screen->completion_shown)
|
||||
{
|
||||
|
|
@ -1288,70 +1316,79 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
|||
|
||||
switch (c)
|
||||
{
|
||||
case 16: /* C-p */
|
||||
case GRUB_TERM_KEY_UP:
|
||||
case GRUB_TERM_CTRL | 'p':
|
||||
if (! previous_line (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 14: /* C-n */
|
||||
case GRUB_TERM_CTRL | 'n':
|
||||
case GRUB_TERM_KEY_DOWN:
|
||||
if (! next_line (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 6: /* C-f */
|
||||
case GRUB_TERM_CTRL | 'f':
|
||||
case GRUB_TERM_KEY_RIGHT:
|
||||
if (! forward_char (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 2: /* C-b */
|
||||
case GRUB_TERM_CTRL | 'b':
|
||||
case GRUB_TERM_KEY_LEFT:
|
||||
if (! backward_char (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 1: /* C-a */
|
||||
case GRUB_TERM_CTRL | 'a':
|
||||
case GRUB_TERM_KEY_HOME:
|
||||
if (! beginning_of_line (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 5: /* C-e */
|
||||
case GRUB_TERM_CTRL | 'e':
|
||||
case GRUB_TERM_KEY_END:
|
||||
if (! end_of_line (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case '\t': /* C-i */
|
||||
case GRUB_TERM_CTRL | 'i':
|
||||
case '\t':
|
||||
if (! complete (screen, prev_c == c, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 4: /* C-d */
|
||||
case GRUB_TERM_CTRL | 'd':
|
||||
case GRUB_TERM_KEY_DC:
|
||||
if (! delete_char (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 8: /* C-h */
|
||||
case GRUB_TERM_CTRL | 'h':
|
||||
case '\b':
|
||||
if (! backward_delete_char (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 11: /* C-k */
|
||||
case GRUB_TERM_CTRL | 'k':
|
||||
if (! kill_line (screen, prev_c == c, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 21: /* C-u */
|
||||
case GRUB_TERM_CTRL | 'u':
|
||||
/* FIXME: What behavior is good for this key? */
|
||||
break;
|
||||
|
||||
case 25: /* C-y */
|
||||
case GRUB_TERM_CTRL | 'y':
|
||||
if (! yank (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case 12: /* C-l */
|
||||
case GRUB_TERM_CTRL | 'l':
|
||||
/* FIXME: centering. */
|
||||
goto refresh;
|
||||
|
||||
case 15: /* C-o */
|
||||
case GRUB_TERM_CTRL | 'o':
|
||||
if (! open_line (screen, 1))
|
||||
goto fail;
|
||||
break;
|
||||
|
|
@ -1366,23 +1403,19 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
|||
destroy_screen (screen);
|
||||
return;
|
||||
|
||||
case 3: /* C-c */
|
||||
case GRUB_TERM_CTRL | 'c':
|
||||
case GRUB_TERM_KEY_F2:
|
||||
grub_cmdline_run (1);
|
||||
goto refresh;
|
||||
|
||||
case 24: /* C-x */
|
||||
{
|
||||
int chars_before = grub_normal_get_char_counter ();
|
||||
run (screen);
|
||||
|
||||
if (chars_before != grub_normal_get_char_counter ())
|
||||
grub_wait_after_message ();
|
||||
}
|
||||
case GRUB_TERM_CTRL | 'x':
|
||||
case GRUB_TERM_KEY_F10:
|
||||
run (screen);
|
||||
goto refresh;
|
||||
|
||||
case 18: /* C-r */
|
||||
case 19: /* C-s */
|
||||
case 20: /* C-t */
|
||||
case GRUB_TERM_CTRL | 'r':
|
||||
case GRUB_TERM_CTRL | 's':
|
||||
case GRUB_TERM_CTRL | 't':
|
||||
/* FIXME */
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,10 +34,19 @@ static grub_uint8_t grub_color_menu_highlight;
|
|||
struct menu_viewer_data
|
||||
{
|
||||
int first, offset;
|
||||
/* The number of entries shown at a time. */
|
||||
int num_entries;
|
||||
grub_menu_t menu;
|
||||
struct grub_term_output *term;
|
||||
};
|
||||
|
||||
static inline int
|
||||
grub_term_cursor_x (struct grub_term_output *term)
|
||||
{
|
||||
return (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
|
||||
- GRUB_TERM_MARGIN - 1);
|
||||
}
|
||||
|
||||
grub_ssize_t
|
||||
grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
|
||||
struct grub_term_output *term)
|
||||
|
|
@ -53,30 +62,45 @@ grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
|
|||
return width;
|
||||
}
|
||||
|
||||
void
|
||||
grub_print_message_indented (const char *msg, int margin_left, int margin_right,
|
||||
struct grub_term_output *term)
|
||||
static int
|
||||
grub_print_message_indented_real (const char *msg, int margin_left,
|
||||
int margin_right,
|
||||
struct grub_term_output *term, int dry_run)
|
||||
{
|
||||
grub_uint32_t *unicode_msg;
|
||||
grub_uint32_t *last_position;
|
||||
|
||||
int msg_len;
|
||||
int ret = 0;
|
||||
|
||||
msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
|
||||
|
||||
if (msg_len < 0)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_print_ucs4 (unicode_msg, last_position, margin_left, margin_right, term);
|
||||
if (dry_run)
|
||||
ret = grub_ucs4_count_lines (unicode_msg, last_position, margin_left,
|
||||
margin_right, term);
|
||||
else
|
||||
grub_print_ucs4 (unicode_msg, last_position, margin_left,
|
||||
margin_right, term);
|
||||
|
||||
grub_free (unicode_msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
grub_print_message_indented (const char *msg, int margin_left, int margin_right,
|
||||
struct grub_term_output *term)
|
||||
{
|
||||
grub_print_message_indented_real (msg, margin_left, margin_right, term, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_border (struct grub_term_output *term)
|
||||
draw_border (struct grub_term_output *term, int num_entries)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
|
|
@ -88,7 +112,7 @@ draw_border (struct grub_term_output *term)
|
|||
grub_putcode (GRUB_UNICODE_HLINE, term);
|
||||
grub_putcode (GRUB_UNICODE_CORNER_UR, term);
|
||||
|
||||
for (i = 0; i < (unsigned) grub_term_num_entries (term); i++)
|
||||
for (i = 0; i < (unsigned) num_entries; i++)
|
||||
{
|
||||
grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
|
||||
grub_putcode (GRUB_UNICODE_VLINE, term);
|
||||
|
|
@ -99,7 +123,7 @@ draw_border (struct grub_term_output *term)
|
|||
}
|
||||
|
||||
grub_term_gotoxy (term, GRUB_TERM_MARGIN,
|
||||
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
|
||||
GRUB_TERM_TOP_BORDER_Y + num_entries + 1);
|
||||
grub_putcode (GRUB_UNICODE_CORNER_LL, term);
|
||||
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
|
||||
grub_putcode (GRUB_UNICODE_HLINE, term);
|
||||
|
|
@ -108,29 +132,27 @@ draw_border (struct grub_term_output *term)
|
|||
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||
|
||||
grub_term_gotoxy (term, GRUB_TERM_MARGIN,
|
||||
(GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)
|
||||
(GRUB_TERM_TOP_BORDER_Y + num_entries
|
||||
+ GRUB_TERM_MARGIN + 1));
|
||||
}
|
||||
|
||||
static void
|
||||
print_message (int nested, int edit, struct grub_term_output *term)
|
||||
static int
|
||||
print_message (int nested, int edit, struct grub_term_output *term, int dry_run)
|
||||
{
|
||||
int ret = 0;
|
||||
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||
|
||||
if (edit)
|
||||
{
|
||||
grub_putcode ('\n', term);
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
|
||||
supported. TAB lists completions. Press F1 to boot, F2=Ctrl-a, F3=Ctrl-e, \
|
||||
F4 for a command-line or ESC to discard edits and return to the GRUB menu."),
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term);
|
||||
#else
|
||||
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
|
||||
supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \
|
||||
if(dry_run)
|
||||
ret++;
|
||||
else
|
||||
grub_putcode ('\n', term);
|
||||
ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \
|
||||
supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \
|
||||
command-line or ESC to discard edits and return to the GRUB menu."),
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term);
|
||||
#endif
|
||||
STANDARD_MARGIN, STANDARD_MARGIN,
|
||||
term, dry_run);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -141,30 +163,34 @@ command-line or ESC to discard edits and return to the GRUB menu."),
|
|||
msg_translated = grub_xasprintf (msg, GRUB_UNICODE_UPARROW,
|
||||
GRUB_UNICODE_DOWNARROW);
|
||||
if (!msg_translated)
|
||||
return;
|
||||
grub_putcode ('\n', term);
|
||||
grub_print_message_indented (msg_translated, STANDARD_MARGIN,
|
||||
STANDARD_MARGIN, term);
|
||||
return 0;
|
||||
if(dry_run)
|
||||
ret++;
|
||||
else
|
||||
grub_putcode ('\n', term);
|
||||
ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN,
|
||||
STANDARD_MARGIN, term, dry_run);
|
||||
|
||||
grub_free (msg_translated);
|
||||
|
||||
if (nested)
|
||||
{
|
||||
grub_print_message_indented
|
||||
ret += grub_print_message_indented_real
|
||||
(_("Press enter to boot the selected OS, "
|
||||
"\'e\' to edit the commands before booting "
|
||||
"or \'c\' for a command-line. ESC to return previous menu.\n"),
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term);
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_print_message_indented
|
||||
ret += grub_print_message_indented_real
|
||||
(_("Press enter to boot the selected OS, "
|
||||
"\'e\' to edit the commands before booting "
|
||||
"or \'c\' for a command-line.\n"),
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term);
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -263,52 +289,56 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
|
|||
}
|
||||
|
||||
static void
|
||||
print_entries (grub_menu_t menu, int first, int offset,
|
||||
struct grub_term_output *term)
|
||||
print_entries (grub_menu_t menu, const struct menu_viewer_data *data)
|
||||
{
|
||||
grub_menu_entry_t e;
|
||||
int i;
|
||||
|
||||
grub_term_gotoxy (term,
|
||||
GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term),
|
||||
grub_term_gotoxy (data->term,
|
||||
GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (data->term),
|
||||
GRUB_TERM_FIRST_ENTRY_Y);
|
||||
|
||||
if (first)
|
||||
grub_putcode (GRUB_UNICODE_UPARROW, term);
|
||||
if (data->first)
|
||||
grub_putcode (GRUB_UNICODE_UPARROW, data->term);
|
||||
else
|
||||
grub_putcode (' ', term);
|
||||
grub_putcode (' ', data->term);
|
||||
|
||||
e = grub_menu_get_entry (menu, first);
|
||||
e = grub_menu_get_entry (menu, data->first);
|
||||
|
||||
for (i = 0; i < grub_term_num_entries (term); i++)
|
||||
for (i = 0; i < data->num_entries; i++)
|
||||
{
|
||||
print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e, term);
|
||||
print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, data->offset == i,
|
||||
e, data->term);
|
||||
if (e)
|
||||
e = e->next;
|
||||
}
|
||||
|
||||
grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X
|
||||
+ grub_term_border_width (term),
|
||||
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
|
||||
grub_term_gotoxy (data->term, GRUB_TERM_LEFT_BORDER_X
|
||||
+ grub_term_border_width (data->term),
|
||||
GRUB_TERM_TOP_BORDER_Y + data->num_entries);
|
||||
|
||||
if (e)
|
||||
grub_putcode (GRUB_UNICODE_DOWNARROW, term);
|
||||
grub_putcode (GRUB_UNICODE_DOWNARROW, data->term);
|
||||
else
|
||||
grub_putcode (' ', term);
|
||||
grub_putcode (' ', data->term);
|
||||
|
||||
grub_term_gotoxy (term, grub_term_cursor_x (term),
|
||||
GRUB_TERM_FIRST_ENTRY_Y + offset);
|
||||
grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
|
||||
GRUB_TERM_FIRST_ENTRY_Y + data->offset);
|
||||
}
|
||||
|
||||
/* Initialize the screen. If NESTED is non-zero, assume that this menu
|
||||
is run from another menu or a command-line. If EDIT is non-zero, show
|
||||
a message for the menu entry editor. */
|
||||
void
|
||||
grub_menu_init_page (int nested, int edit,
|
||||
grub_menu_init_page (int nested, int edit, int *num_entries,
|
||||
struct grub_term_output *term)
|
||||
{
|
||||
grub_uint8_t old_color_normal, old_color_highlight;
|
||||
|
||||
/* 3 lines for timeout message and bottom margin. 2 lines for the border. */
|
||||
*num_entries = grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y
|
||||
- (print_message (nested, edit, term, 1) + 3) - 2;
|
||||
|
||||
grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
|
||||
|
||||
/* By default, use the same colors for the menu. */
|
||||
|
|
@ -323,9 +353,9 @@ grub_menu_init_page (int nested, int edit,
|
|||
|
||||
grub_normal_init_page (term);
|
||||
grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
|
||||
draw_border (term);
|
||||
draw_border (term, *num_entries);
|
||||
grub_term_setcolor (term, old_color_normal, old_color_highlight);
|
||||
print_message (nested, edit, term);
|
||||
print_message (nested, edit, term, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -366,10 +396,10 @@ menu_text_set_chosen_entry (int entry, void *dataptr)
|
|||
int complete_redraw = 0;
|
||||
|
||||
data->offset = entry - data->first;
|
||||
if (data->offset > grub_term_num_entries (data->term) - 1)
|
||||
if (data->offset > data->num_entries - 1)
|
||||
{
|
||||
data->first = entry - (grub_term_num_entries (data->term) - 1);
|
||||
data->offset = grub_term_num_entries (data->term) - 1;
|
||||
data->first = entry - (data->num_entries - 1);
|
||||
data->offset = data->num_entries - 1;
|
||||
complete_redraw = 1;
|
||||
}
|
||||
if (data->offset < 0)
|
||||
|
|
@ -379,7 +409,7 @@ menu_text_set_chosen_entry (int entry, void *dataptr)
|
|||
complete_redraw = 1;
|
||||
}
|
||||
if (complete_redraw)
|
||||
print_entries (data->menu, data->first, data->offset, data->term);
|
||||
print_entries (data->menu, data);
|
||||
else
|
||||
{
|
||||
print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0,
|
||||
|
|
@ -443,15 +473,17 @@ grub_menu_try_text (struct grub_term_output *term,
|
|||
|
||||
data->offset = entry;
|
||||
data->first = 0;
|
||||
if (data->offset > grub_term_num_entries (data->term) - 1)
|
||||
{
|
||||
data->first = data->offset - (grub_term_num_entries (data->term) - 1);
|
||||
data->offset = grub_term_num_entries (data->term) - 1;
|
||||
}
|
||||
|
||||
grub_term_setcursor (data->term, 0);
|
||||
grub_menu_init_page (nested, 0, data->term);
|
||||
print_entries (menu, data->first, data->offset, data->term);
|
||||
grub_menu_init_page (nested, 0, &data->num_entries, data->term);
|
||||
|
||||
if (data->offset > data->num_entries - 1)
|
||||
{
|
||||
data->first = data->offset - (data->num_entries - 1);
|
||||
data->offset = data->num_entries - 1;
|
||||
}
|
||||
|
||||
print_entries (menu, data);
|
||||
grub_term_refresh (data->term);
|
||||
grub_menu_register_viewer (instance);
|
||||
|
||||
|
|
|
|||
|
|
@ -112,14 +112,13 @@ grub_normal_print_device_info (const char *name)
|
|||
grub_printf ("%s", _("Not a known filesystem"));
|
||||
|
||||
if (dev->disk->partition)
|
||||
grub_printf (_(" - Partition start at %u"),
|
||||
grub_partition_get_start (dev->disk->partition));
|
||||
grub_printf (_(" - Partition start at %llu"),
|
||||
(unsigned long long) grub_partition_get_start (dev->disk->partition));
|
||||
if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN)
|
||||
grub_printf (_(" - Total size unknown"),
|
||||
grub_disk_get_size (dev->disk));
|
||||
grub_puts_ (" - Total size unknown");
|
||||
else
|
||||
grub_printf (_(" - Total size %u sectors"),
|
||||
grub_disk_get_size (dev->disk));
|
||||
grub_printf (_(" - Total size %llu sectors"),
|
||||
(unsigned long long) grub_disk_get_size (dev->disk));
|
||||
|
||||
grub_device_close (dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <grub/env.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
struct term_state
|
||||
{
|
||||
|
|
@ -42,17 +43,9 @@ static struct term_state *term_states = NULL;
|
|||
/* If the more pager is active. */
|
||||
static int grub_more;
|
||||
|
||||
static int grub_normal_char_counter = 0;
|
||||
|
||||
static void
|
||||
putcode_real (grub_uint32_t code, struct grub_term_output *term);
|
||||
|
||||
int
|
||||
grub_normal_get_char_counter (void)
|
||||
{
|
||||
return grub_normal_char_counter;
|
||||
}
|
||||
|
||||
void
|
||||
grub_normal_reset_more (void)
|
||||
{
|
||||
|
|
@ -71,7 +64,9 @@ print_more (void)
|
|||
|
||||
pos = grub_term_save_pos ();
|
||||
|
||||
grub_utf8_to_ucs4_alloc ("--MORE--", &unicode_str,
|
||||
/* TRANSLATORS: This has to fit on one line. It's ok to include few
|
||||
words but don't write poems. */
|
||||
grub_utf8_to_ucs4_alloc (_("--MORE--"), &unicode_str,
|
||||
&unicode_last_position);
|
||||
|
||||
if (!unicode_str)
|
||||
|
|
@ -99,16 +94,16 @@ print_more (void)
|
|||
grub_term_restore_pos (pos);
|
||||
grub_free (pos);
|
||||
|
||||
/* Scroll one lines or an entire page, depending on the key. */
|
||||
/* Scroll one line or an entire page, depending on the key. */
|
||||
|
||||
if (key == '\r' || key =='\n')
|
||||
grub_normal_reset_more ();
|
||||
else
|
||||
{
|
||||
static struct term_state *state;
|
||||
for (state = term_states; state; state = state->next)
|
||||
state->num_lines -= 2;
|
||||
state->num_lines--;
|
||||
}
|
||||
else
|
||||
grub_normal_reset_more ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -384,8 +379,8 @@ read_terminal_list (const char *prefix)
|
|||
if (! cur->modname)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
grub_free (cur);
|
||||
grub_free (cur->name);
|
||||
grub_free (cur);
|
||||
continue;
|
||||
}
|
||||
cur->next = *target;
|
||||
|
|
@ -409,8 +404,6 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
|
|||
.estimated_width = 1
|
||||
};
|
||||
|
||||
grub_normal_char_counter++;
|
||||
|
||||
if (c->base == '\t' && term->getxy)
|
||||
{
|
||||
int n;
|
||||
|
|
@ -525,14 +518,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++)
|
||||
{
|
||||
|
|
@ -562,7 +557,7 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
|||
if (line_width > max_width && last_space > line_start)
|
||||
ptr = last_space;
|
||||
else if (line_width > max_width
|
||||
&& line_start == str && startwidth != 0)
|
||||
&& line_start == str && line_width - lastspacewidth < max_width - 5)
|
||||
{
|
||||
ptr = str;
|
||||
lastspacewidth = startwidth;
|
||||
|
|
@ -570,50 +565,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 *
|
||||
|
|
@ -682,7 +686,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);
|
||||
|
|
@ -716,15 +720,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
|
||||
|
|
@ -753,16 +761,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
|
||||
|
|
@ -772,9 +794,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)
|
||||
|
|
@ -823,7 +854,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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue