mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-08-27 16:01:14 +00:00
1. change some directory structure for the build script
2. add build script and document see DOC/BuildVentoyFromSource.txt for detail
This commit is contained in:
161
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gfxmenu.c
Normal file
161
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gfxmenu.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/* gfxmenu.c - Graphical menu interface controller. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/video.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/bitmap.h>
|
||||
#include <grub/bitmap_scale.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/gfxwidgets.h>
|
||||
#include <grub/menu.h>
|
||||
#include <grub/menu_viewer.h>
|
||||
#include <grub/gfxmenu_model.h>
|
||||
#include <grub/gfxmenu_view.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
extern int g_ventoy_menu_refresh;
|
||||
|
||||
static grub_gfxmenu_view_t cached_view;
|
||||
|
||||
static void
|
||||
grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
/* FIXME: Previously 't' changed to text menu is it necessary? */
|
||||
static grub_err_t
|
||||
grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
|
||||
{
|
||||
int force_refresh = 0;
|
||||
grub_gfxmenu_view_t view = NULL;
|
||||
const char *theme_path;
|
||||
char *full_theme_path = 0;
|
||||
struct grub_menu_viewer *instance;
|
||||
grub_err_t err;
|
||||
struct grub_video_mode_info mode_info;
|
||||
|
||||
theme_path = grub_env_get ("theme");
|
||||
if (! theme_path)
|
||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"),
|
||||
"theme");
|
||||
|
||||
err = grub_video_get_info (&mode_info);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
instance = grub_zalloc (sizeof (*instance));
|
||||
if (!instance)
|
||||
return grub_errno;
|
||||
|
||||
if (theme_path[0] != '/' && theme_path[0] != '(')
|
||||
{
|
||||
const char *prefix;
|
||||
prefix = grub_env_get ("prefix");
|
||||
full_theme_path = grub_xasprintf ("%s/themes/%s",
|
||||
prefix,
|
||||
theme_path);
|
||||
}
|
||||
|
||||
if (g_ventoy_menu_refresh)
|
||||
{
|
||||
g_ventoy_menu_refresh = 0;
|
||||
force_refresh = 1;
|
||||
}
|
||||
|
||||
if (force_refresh ||
|
||||
!cached_view || grub_strcmp (cached_view->theme_path,
|
||||
full_theme_path ? : theme_path) != 0
|
||||
|| cached_view->screen.width != mode_info.width
|
||||
|| cached_view->screen.height != mode_info.height)
|
||||
{
|
||||
grub_gfxmenu_view_destroy (cached_view);
|
||||
/* Create the view. */
|
||||
cached_view = grub_gfxmenu_view_new (full_theme_path ? : theme_path,
|
||||
mode_info.width,
|
||||
mode_info.height);
|
||||
}
|
||||
grub_free (full_theme_path);
|
||||
|
||||
if (! cached_view)
|
||||
{
|
||||
grub_free (instance);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
view = cached_view;
|
||||
|
||||
view->double_repaint = (mode_info.mode_type
|
||||
& GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
|
||||
&& !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
|
||||
view->selected = entry;
|
||||
view->menu = menu;
|
||||
view->nested = nested;
|
||||
view->first_timeout = -1;
|
||||
|
||||
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
|
||||
if (view->double_repaint)
|
||||
{
|
||||
grub_video_swap_buffers ();
|
||||
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
|
||||
}
|
||||
|
||||
grub_gfxmenu_view_draw (view);
|
||||
|
||||
instance->data = view;
|
||||
instance->set_chosen_entry = grub_gfxmenu_set_chosen_entry;
|
||||
instance->fini = grub_gfxmenu_viewer_fini;
|
||||
instance->print_timeout = grub_gfxmenu_print_timeout;
|
||||
instance->clear_timeout = grub_gfxmenu_clear_timeout;
|
||||
|
||||
grub_menu_register_viewer (instance);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
GRUB_MOD_INIT (gfxmenu)
|
||||
{
|
||||
struct grub_term_output *term;
|
||||
|
||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||
if (grub_gfxmenu_try_hook && term->fullscreen)
|
||||
{
|
||||
term->fullscreen ();
|
||||
break;
|
||||
}
|
||||
|
||||
grub_gfxmenu_try_hook = grub_gfxmenu_try;
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (gfxmenu)
|
||||
{
|
||||
grub_gfxmenu_view_destroy (cached_view);
|
||||
grub_gfxmenu_try_hook = NULL;
|
||||
}
|
295
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c
Normal file
295
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c
Normal file
@@ -0,0 +1,295 @@
|
||||
/* gui_label.c - GUI component to display a line of text. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/gui.h>
|
||||
#include <grub/font.h>
|
||||
#include <grub/gui_string_util.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/color.h>
|
||||
#include <grub/env.h>
|
||||
|
||||
extern int g_ventoy_memdisk_mode;
|
||||
extern int g_ventoy_iso_raw;
|
||||
extern int g_ventoy_iso_uefi_drv;
|
||||
|
||||
static const char *align_options[] =
|
||||
{
|
||||
"left",
|
||||
"center",
|
||||
"right",
|
||||
0
|
||||
};
|
||||
|
||||
enum align_mode {
|
||||
align_left,
|
||||
align_center,
|
||||
align_right
|
||||
};
|
||||
|
||||
struct grub_gui_label
|
||||
{
|
||||
struct grub_gui_component comp;
|
||||
|
||||
grub_gui_container_t parent;
|
||||
grub_video_rect_t bounds;
|
||||
char *id;
|
||||
int visible;
|
||||
char *text;
|
||||
char *template;
|
||||
grub_font_t font;
|
||||
grub_video_rgba_color_t color;
|
||||
int value;
|
||||
enum align_mode align;
|
||||
};
|
||||
|
||||
typedef struct grub_gui_label *grub_gui_label_t;
|
||||
|
||||
static void
|
||||
label_destroy (void *vself)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self->text);
|
||||
grub_free (self->template);
|
||||
grub_free (self);
|
||||
}
|
||||
|
||||
static const char *
|
||||
label_get_id (void *vself)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
return self->id;
|
||||
}
|
||||
|
||||
static int
|
||||
label_is_instance (void *vself __attribute__((unused)), const char *type)
|
||||
{
|
||||
return grub_strcmp (type, "component") == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
label_paint (void *vself, const grub_video_rect_t *region)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
|
||||
if (! self->visible)
|
||||
return;
|
||||
|
||||
if (!grub_video_have_common_points (region, &self->bounds))
|
||||
return;
|
||||
|
||||
/* Calculate the starting x coordinate. */
|
||||
int left_x;
|
||||
if (self->align == align_left)
|
||||
left_x = 0;
|
||||
else if (self->align == align_center)
|
||||
left_x = (self->bounds.width
|
||||
- grub_font_get_string_width (self->font, self->text)) / 2;
|
||||
else if (self->align == align_right)
|
||||
left_x = (self->bounds.width
|
||||
- grub_font_get_string_width (self->font, self->text));
|
||||
else
|
||||
return; /* Invalid alignment. */
|
||||
|
||||
if (left_x < 0 || left_x > (int) self->bounds.width)
|
||||
left_x = 0;
|
||||
|
||||
grub_video_rect_t vpsave;
|
||||
grub_gui_set_viewport (&self->bounds, &vpsave);
|
||||
grub_font_draw_string (self->text,
|
||||
self->font,
|
||||
grub_video_map_rgba_color (self->color),
|
||||
left_x,
|
||||
grub_font_get_ascent (self->font));
|
||||
grub_gui_restore_viewport (&vpsave);
|
||||
}
|
||||
|
||||
static void
|
||||
label_set_parent (void *vself, grub_gui_container_t parent)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
self->parent = parent;
|
||||
}
|
||||
|
||||
static grub_gui_container_t
|
||||
label_get_parent (void *vself)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
return self->parent;
|
||||
}
|
||||
|
||||
static void
|
||||
label_set_bounds (void *vself, const grub_video_rect_t *bounds)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
self->bounds = *bounds;
|
||||
}
|
||||
|
||||
static void
|
||||
label_get_bounds (void *vself, grub_video_rect_t *bounds)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
*bounds = self->bounds;
|
||||
}
|
||||
|
||||
static void
|
||||
label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
*width = grub_font_get_string_width (self->font, self->text);
|
||||
*height = (grub_font_get_ascent (self->font)
|
||||
+ grub_font_get_descent (self->font));
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
|
||||
static void
|
||||
label_set_state (void *vself, int visible, int start __attribute__ ((unused)),
|
||||
int current, int end __attribute__ ((unused)))
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
self->value = -current;
|
||||
self->visible = visible;
|
||||
grub_free (self->text);
|
||||
self->text = grub_xasprintf (self->template ? : "%d", self->value);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
label_set_property (void *vself, const char *name, const char *value)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
if (grub_strcmp (name, "text") == 0)
|
||||
{
|
||||
grub_free (self->text);
|
||||
grub_free (self->template);
|
||||
if (! value)
|
||||
{
|
||||
self->template = NULL;
|
||||
self->text = grub_strdup ("");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (grub_strcmp (value, "@KEYMAP_LONG@") == 0)
|
||||
value = _("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.");
|
||||
else if (grub_strcmp (value, "@KEYMAP_MIDDLE@") == 0)
|
||||
value = _("Press enter to boot the selected OS, "
|
||||
"`e' to edit the commands before booting "
|
||||
"or `c' for a command-line.");
|
||||
else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0)
|
||||
value = _("enter: boot, `e': options, `c': cmd-line");
|
||||
/* FIXME: Add more templates here if needed. */
|
||||
|
||||
else if (grub_strcmp (value, "@VTOY_MEM_DISK@") == 0) {
|
||||
value = g_ventoy_memdisk_mode ? grub_env_get("VTOY_MEM_DISK_STR") : " ";
|
||||
}
|
||||
else if (grub_strcmp (value, "@VTOY_ISO_RAW@") == 0) {
|
||||
value = g_ventoy_iso_raw ? grub_env_get("VTOY_ISO_RAW_STR") : " ";
|
||||
}
|
||||
else if (grub_strcmp (value, "@VTOY_ISO_UEFI_DRV@") == 0) {
|
||||
value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " ";
|
||||
}
|
||||
else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) {
|
||||
value = grub_env_get("VTOY_HOTKEY_TIP");
|
||||
if (value == NULL) {
|
||||
value = _(" ");
|
||||
}
|
||||
}
|
||||
|
||||
self->template = grub_strdup (value);
|
||||
self->text = grub_xasprintf (value, self->value);
|
||||
}
|
||||
}
|
||||
else if (grub_strcmp (name, "font") == 0)
|
||||
{
|
||||
self->font = grub_font_get (value);
|
||||
}
|
||||
else if (grub_strcmp (name, "color") == 0)
|
||||
{
|
||||
grub_video_parse_color (value, &self->color);
|
||||
}
|
||||
else if (grub_strcmp (name, "align") == 0)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; align_options[i]; i++)
|
||||
{
|
||||
if (grub_strcmp (align_options[i], value) == 0)
|
||||
{
|
||||
self->align = i; /* Set the alignment mode. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (grub_strcmp (name, "visible") == 0)
|
||||
{
|
||||
self->visible = grub_strcmp (value, "false") != 0;
|
||||
}
|
||||
else if (grub_strcmp (name, "id") == 0)
|
||||
{
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self->id);
|
||||
if (value)
|
||||
self->id = grub_strdup (value);
|
||||
else
|
||||
self->id = 0;
|
||||
if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
|
||||
== 0)
|
||||
grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
|
||||
label_set_state);
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic error "-Wformat-nonliteral"
|
||||
|
||||
static struct grub_gui_component_ops label_ops =
|
||||
{
|
||||
.destroy = label_destroy,
|
||||
.get_id = label_get_id,
|
||||
.is_instance = label_is_instance,
|
||||
.paint = label_paint,
|
||||
.set_parent = label_set_parent,
|
||||
.get_parent = label_get_parent,
|
||||
.set_bounds = label_set_bounds,
|
||||
.get_bounds = label_get_bounds,
|
||||
.get_minimal_size = label_get_minimal_size,
|
||||
.set_property = label_set_property
|
||||
};
|
||||
|
||||
grub_gui_component_t
|
||||
grub_gui_label_new (void)
|
||||
{
|
||||
grub_gui_label_t label;
|
||||
label = grub_zalloc (sizeof (*label));
|
||||
if (! label)
|
||||
return 0;
|
||||
label->comp.ops = &label_ops;
|
||||
label->visible = 1;
|
||||
label->text = grub_strdup ("");
|
||||
label->font = grub_font_get ("Unknown Regular 16");
|
||||
label->color.red = 0;
|
||||
label->color.green = 0;
|
||||
label->color.blue = 0;
|
||||
label->color.alpha = 255;
|
||||
label->align = align_left;
|
||||
return (grub_gui_component_t) label;
|
||||
}
|
214
GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c
Normal file
214
GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/* env.c - Environment variables */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/env.h>
|
||||
#include <grub/env_private.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
struct menu_pointer
|
||||
{
|
||||
grub_menu_t menu;
|
||||
struct menu_pointer *prev;
|
||||
};
|
||||
|
||||
static struct menu_pointer initial_menu;
|
||||
static struct menu_pointer *current_menu = &initial_menu;
|
||||
|
||||
void
|
||||
grub_env_unset_menu (void)
|
||||
{
|
||||
current_menu->menu = NULL;
|
||||
}
|
||||
|
||||
grub_menu_t
|
||||
grub_env_get_menu (void)
|
||||
{
|
||||
return current_menu->menu;
|
||||
}
|
||||
|
||||
void
|
||||
grub_env_set_menu (grub_menu_t nmenu)
|
||||
{
|
||||
current_menu->menu = nmenu;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_env_new_context (int export_all)
|
||||
{
|
||||
struct grub_env_context *context;
|
||||
int i;
|
||||
struct menu_pointer *menu;
|
||||
|
||||
context = grub_zalloc (sizeof (*context));
|
||||
if (! context)
|
||||
return grub_errno;
|
||||
menu = grub_zalloc (sizeof (*menu));
|
||||
if (! menu)
|
||||
{
|
||||
grub_free (context);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
context->prev = grub_current_context;
|
||||
grub_current_context = context;
|
||||
|
||||
menu->prev = current_menu;
|
||||
current_menu = menu;
|
||||
|
||||
/* Copy exported variables. */
|
||||
for (i = 0; i < HASHSZ; i++)
|
||||
{
|
||||
struct grub_env_var *var;
|
||||
|
||||
for (var = context->prev->vars[i]; var; var = var->next)
|
||||
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 (1);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct grub_env_context *context;
|
||||
int i;
|
||||
struct menu_pointer *menu;
|
||||
|
||||
if (! grub_current_context->prev)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"cannot close the initial context");
|
||||
|
||||
/* Free the variables associated with this context. */
|
||||
for (i = 0; i < HASHSZ; i++)
|
||||
{
|
||||
struct grub_env_var *p, *q;
|
||||
|
||||
for (p = grub_current_context->vars[i]; p; p = q)
|
||||
{
|
||||
q = p->next;
|
||||
grub_free (p->name);
|
||||
grub_free (p->value);
|
||||
grub_free (p);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the previous context. */
|
||||
context = grub_current_context->prev;
|
||||
grub_free (grub_current_context);
|
||||
grub_current_context = context;
|
||||
|
||||
menu = current_menu->prev;
|
||||
if (current_menu->menu)
|
||||
grub_normal_free_menu (current_menu->menu);
|
||||
grub_free (current_menu);
|
||||
current_menu = menu;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_env_extractor_close (int source)
|
||||
{
|
||||
grub_menu_t menu = NULL;
|
||||
grub_menu_entry_t *last;
|
||||
grub_err_t err;
|
||||
|
||||
if (source)
|
||||
{
|
||||
menu = grub_env_get_menu ();
|
||||
grub_env_unset_menu ();
|
||||
}
|
||||
err = grub_env_context_close ();
|
||||
|
||||
if (source && menu)
|
||||
{
|
||||
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;
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("one argument expected"));
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
grub_env_export (args[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
grub_context_init (void)
|
||||
{
|
||||
export_cmd = grub_register_command ("export", grub_cmd_export,
|
||||
N_("ENVVAR [ENVVAR] ..."),
|
||||
N_("Export variables."));
|
||||
}
|
||||
|
||||
void
|
||||
grub_context_fini (void)
|
||||
{
|
||||
grub_unregister_command (export_cmd);
|
||||
}
|
605
GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c
Normal file
605
GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c
Normal file
@@ -0,0 +1,605 @@
|
||||
/* menu_text.c - Basic text menu implementation. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/normal.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/loader.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/menu_viewer.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/charset.h>
|
||||
|
||||
static grub_uint8_t grub_color_menu_normal;
|
||||
static grub_uint8_t grub_color_menu_highlight;
|
||||
|
||||
struct menu_viewer_data
|
||||
{
|
||||
int first, offset;
|
||||
struct grub_term_screen_geometry geo;
|
||||
enum {
|
||||
TIMEOUT_UNKNOWN,
|
||||
TIMEOUT_NORMAL,
|
||||
TIMEOUT_TERSE,
|
||||
TIMEOUT_TERSE_NO_MARGIN
|
||||
} timeout_msg;
|
||||
grub_menu_t menu;
|
||||
struct grub_term_output *term;
|
||||
};
|
||||
|
||||
static inline int
|
||||
grub_term_cursor_x (const struct grub_term_screen_geometry *geo)
|
||||
{
|
||||
return (geo->first_entry_x + geo->entry_width);
|
||||
}
|
||||
|
||||
grub_size_t
|
||||
grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
|
||||
struct grub_term_output *term)
|
||||
{
|
||||
grub_ssize_t width = 0;
|
||||
|
||||
while (str < last_position)
|
||||
{
|
||||
struct grub_unicode_glyph glyph;
|
||||
glyph.ncomb = 0;
|
||||
str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph);
|
||||
width += grub_term_getcharwidth (term, &glyph);
|
||||
grub_unicode_destroy_glyph (&glyph);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
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;
|
||||
grub_size_t msg_len = grub_strlen (msg) + 2;
|
||||
int ret = 0;
|
||||
|
||||
unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t));
|
||||
|
||||
if (!unicode_msg)
|
||||
return 0;
|
||||
|
||||
msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len,
|
||||
(grub_uint8_t *) msg, -1, 0);
|
||||
|
||||
last_position = unicode_msg + msg_len;
|
||||
*last_position = 0;
|
||||
|
||||
if (dry_run)
|
||||
ret = grub_ucs4_count_lines (unicode_msg, last_position, margin_left,
|
||||
margin_right, term);
|
||||
else
|
||||
grub_print_ucs4_menu (unicode_msg, last_position, margin_left,
|
||||
margin_right, term, 0, -1, 0, 0);
|
||||
|
||||
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, const struct grub_term_screen_geometry *geo)
|
||||
{
|
||||
int i;
|
||||
|
||||
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||
|
||||
grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
|
||||
geo->first_entry_y - 1 });
|
||||
grub_putcode (GRUB_UNICODE_CORNER_UL, term);
|
||||
for (i = 0; i < geo->entry_width + 1; i++)
|
||||
grub_putcode (GRUB_UNICODE_HLINE, term);
|
||||
grub_putcode (GRUB_UNICODE_CORNER_UR, term);
|
||||
|
||||
for (i = 0; i < geo->num_entries; i++)
|
||||
{
|
||||
grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
|
||||
geo->first_entry_y + i });
|
||||
grub_putcode (GRUB_UNICODE_VLINE, term);
|
||||
grub_term_gotoxy (term,
|
||||
(struct grub_term_coordinate) { geo->first_entry_x + geo->entry_width + 1,
|
||||
geo->first_entry_y + i });
|
||||
grub_putcode (GRUB_UNICODE_VLINE, term);
|
||||
}
|
||||
|
||||
grub_term_gotoxy (term,
|
||||
(struct grub_term_coordinate) { geo->first_entry_x - 1,
|
||||
geo->first_entry_y - 1 + geo->num_entries + 1 });
|
||||
grub_putcode (GRUB_UNICODE_CORNER_LL, term);
|
||||
for (i = 0; i < geo->entry_width + 1; i++)
|
||||
grub_putcode (GRUB_UNICODE_HLINE, term);
|
||||
grub_putcode (GRUB_UNICODE_CORNER_LR, term);
|
||||
|
||||
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||
|
||||
grub_term_gotoxy (term,
|
||||
(struct grub_term_coordinate) { geo->first_entry_x - 1,
|
||||
(geo->first_entry_y - 1 + geo->num_entries
|
||||
+ GRUB_TERM_MARGIN + 1) });
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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, dry_run);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *msg_translated;
|
||||
|
||||
msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which "
|
||||
"entry is highlighted."),
|
||||
GRUB_UNICODE_UPARROW,
|
||||
GRUB_UNICODE_DOWNARROW);
|
||||
if (!msg_translated)
|
||||
return 0;
|
||||
ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN,
|
||||
STANDARD_MARGIN, term, dry_run);
|
||||
|
||||
grub_free (msg_translated);
|
||||
|
||||
if (nested)
|
||||
{
|
||||
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."),
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += grub_print_message_indented_real("\n", STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
|
||||
ret += grub_print_message_indented_real(grub_env_get("VTOY_TEXT_MENU_VER"),
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
|
||||
ret += grub_print_message_indented_real("\n", STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
ret += grub_print_message_indented_real(grub_env_get("VTOY_HOTKEY_TIP"),
|
||||
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
print_entry (int y, int highlight, grub_menu_entry_t entry,
|
||||
const struct menu_viewer_data *data)
|
||||
{
|
||||
const char *title;
|
||||
grub_size_t title_len;
|
||||
grub_ssize_t len;
|
||||
grub_uint32_t *unicode_title;
|
||||
grub_ssize_t i;
|
||||
grub_uint8_t old_color_normal, old_color_highlight;
|
||||
|
||||
title = entry ? entry->title : "";
|
||||
title_len = grub_strlen (title);
|
||||
unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
|
||||
if (! unicode_title)
|
||||
/* XXX How to show this error? */
|
||||
return;
|
||||
|
||||
len = grub_utf8_to_ucs4 (unicode_title, title_len,
|
||||
(grub_uint8_t *) title, -1, 0);
|
||||
if (len < 0)
|
||||
{
|
||||
/* It is an invalid sequence. */
|
||||
grub_free (unicode_title);
|
||||
return;
|
||||
}
|
||||
|
||||
old_color_normal = grub_term_normal_color;
|
||||
old_color_highlight = grub_term_highlight_color;
|
||||
grub_term_normal_color = grub_color_menu_normal;
|
||||
grub_term_highlight_color = grub_color_menu_highlight;
|
||||
grub_term_setcolorstate (data->term, highlight
|
||||
? GRUB_TERM_COLOR_HIGHLIGHT
|
||||
: GRUB_TERM_COLOR_NORMAL);
|
||||
|
||||
grub_term_gotoxy (data->term, (struct grub_term_coordinate) {
|
||||
data->geo.first_entry_x, y });
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (unicode_title[i] == '\n' || unicode_title[i] == '\b'
|
||||
|| unicode_title[i] == '\r' || unicode_title[i] == '\e')
|
||||
unicode_title[i] = ' ';
|
||||
|
||||
if (data->geo.num_entries > 1)
|
||||
grub_putcode (highlight ? '*' : ' ', data->term);
|
||||
|
||||
grub_print_ucs4_menu (unicode_title,
|
||||
unicode_title + len,
|
||||
0,
|
||||
data->geo.right_margin,
|
||||
data->term, 0, 1,
|
||||
GRUB_UNICODE_RIGHTARROW, 0);
|
||||
|
||||
grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL);
|
||||
grub_term_gotoxy (data->term,
|
||||
(struct grub_term_coordinate) {
|
||||
grub_term_cursor_x (&data->geo), y });
|
||||
|
||||
grub_term_normal_color = old_color_normal;
|
||||
grub_term_highlight_color = old_color_highlight;
|
||||
|
||||
grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL);
|
||||
grub_free (unicode_title);
|
||||
}
|
||||
|
||||
static void
|
||||
print_entries (grub_menu_t menu, const struct menu_viewer_data *data)
|
||||
{
|
||||
grub_menu_entry_t e;
|
||||
int i;
|
||||
|
||||
grub_term_gotoxy (data->term,
|
||||
(struct grub_term_coordinate) {
|
||||
data->geo.first_entry_x + data->geo.entry_width
|
||||
+ data->geo.border + 1,
|
||||
data->geo.first_entry_y });
|
||||
|
||||
if (data->geo.num_entries != 1)
|
||||
{
|
||||
if (data->first)
|
||||
grub_putcode (GRUB_UNICODE_UPARROW, data->term);
|
||||
else
|
||||
grub_putcode (' ', data->term);
|
||||
}
|
||||
e = grub_menu_get_entry (menu, data->first);
|
||||
|
||||
for (i = 0; i < data->geo.num_entries; i++)
|
||||
{
|
||||
print_entry (data->geo.first_entry_y + i, data->offset == i,
|
||||
e, data);
|
||||
if (e)
|
||||
e = e->next;
|
||||
}
|
||||
|
||||
grub_term_gotoxy (data->term,
|
||||
(struct grub_term_coordinate) { data->geo.first_entry_x + data->geo.entry_width
|
||||
+ data->geo.border + 1,
|
||||
data->geo.first_entry_y + data->geo.num_entries - 1 });
|
||||
if (data->geo.num_entries == 1)
|
||||
{
|
||||
if (data->first && e)
|
||||
grub_putcode (GRUB_UNICODE_UPDOWNARROW, data->term);
|
||||
else if (data->first)
|
||||
grub_putcode (GRUB_UNICODE_UPARROW, data->term);
|
||||
else if (e)
|
||||
grub_putcode (GRUB_UNICODE_DOWNARROW, data->term);
|
||||
else
|
||||
grub_putcode (' ', data->term);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e)
|
||||
grub_putcode (GRUB_UNICODE_DOWNARROW, data->term);
|
||||
else
|
||||
grub_putcode (' ', data->term);
|
||||
}
|
||||
|
||||
grub_term_gotoxy (data->term,
|
||||
(struct grub_term_coordinate) { grub_term_cursor_x (&data->geo),
|
||||
data->geo.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,
|
||||
struct grub_term_screen_geometry *geo,
|
||||
struct grub_term_output *term)
|
||||
{
|
||||
grub_uint8_t old_color_normal, old_color_highlight;
|
||||
int msg_num_lines;
|
||||
int bottom_message = 1;
|
||||
int empty_lines = 1;
|
||||
int version_msg = 1;
|
||||
|
||||
geo->border = 1;
|
||||
geo->first_entry_x = 1 /* margin */ + 1 /* border */;
|
||||
geo->entry_width = grub_term_width (term) - 5;
|
||||
|
||||
geo->first_entry_y = 2 /* two empty lines*/
|
||||
+ 1 /* GNU GRUB version text */ + 1 /* top border */;
|
||||
|
||||
geo->timeout_lines = 2;
|
||||
|
||||
/* 3 lines for timeout message and bottom margin. 2 lines for the border. */
|
||||
geo->num_entries = grub_term_height (term) - geo->first_entry_y
|
||||
- 1 /* bottom border */
|
||||
- 1 /* empty line before info message*/
|
||||
- geo->timeout_lines /* timeout */
|
||||
- 1 /* empty final line */;
|
||||
msg_num_lines = print_message (nested, edit, term, 1);
|
||||
if (geo->num_entries - msg_num_lines < 3
|
||||
|| geo->entry_width < 10)
|
||||
{
|
||||
geo->num_entries += 4;
|
||||
geo->first_entry_y -= 2;
|
||||
empty_lines = 0;
|
||||
geo->first_entry_x -= 1;
|
||||
geo->entry_width += 1;
|
||||
}
|
||||
if (geo->num_entries - msg_num_lines < 3
|
||||
|| geo->entry_width < 10)
|
||||
{
|
||||
geo->num_entries += 2;
|
||||
geo->first_entry_y -= 1;
|
||||
geo->first_entry_x -= 1;
|
||||
geo->entry_width += 2;
|
||||
geo->border = 0;
|
||||
}
|
||||
|
||||
if (geo->entry_width <= 0)
|
||||
geo->entry_width = 1;
|
||||
|
||||
if (geo->num_entries - msg_num_lines < 3
|
||||
&& geo->timeout_lines == 2)
|
||||
{
|
||||
geo->timeout_lines = 1;
|
||||
geo->num_entries++;
|
||||
}
|
||||
|
||||
if (geo->num_entries - msg_num_lines < 3)
|
||||
{
|
||||
geo->num_entries += 1;
|
||||
geo->first_entry_y -= 1;
|
||||
version_msg = 0;
|
||||
}
|
||||
|
||||
if (geo->num_entries - msg_num_lines >= 2)
|
||||
geo->num_entries -= msg_num_lines;
|
||||
else
|
||||
bottom_message = 0;
|
||||
|
||||
/* By default, use the same colors for the menu. */
|
||||
old_color_normal = grub_term_normal_color;
|
||||
old_color_highlight = grub_term_highlight_color;
|
||||
grub_color_menu_normal = grub_term_normal_color;
|
||||
grub_color_menu_highlight = grub_term_highlight_color;
|
||||
|
||||
/* Then give user a chance to replace them. */
|
||||
grub_parse_color_name_pair (&grub_color_menu_normal,
|
||||
grub_env_get ("menu_color_normal"));
|
||||
grub_parse_color_name_pair (&grub_color_menu_highlight,
|
||||
grub_env_get ("menu_color_highlight"));
|
||||
|
||||
if (version_msg)
|
||||
grub_normal_init_page (term, empty_lines);
|
||||
else
|
||||
grub_term_cls (term);
|
||||
|
||||
grub_term_normal_color = grub_color_menu_normal;
|
||||
grub_term_highlight_color = grub_color_menu_highlight;
|
||||
if (geo->border)
|
||||
draw_border (term, geo);
|
||||
grub_term_normal_color = old_color_normal;
|
||||
grub_term_highlight_color = old_color_highlight;
|
||||
geo->timeout_y = geo->first_entry_y + geo->num_entries
|
||||
+ geo->border + empty_lines;
|
||||
if (bottom_message)
|
||||
{
|
||||
grub_term_gotoxy (term,
|
||||
(struct grub_term_coordinate) { GRUB_TERM_MARGIN,
|
||||
geo->timeout_y });
|
||||
|
||||
print_message (nested, edit, term, 0);
|
||||
geo->timeout_y += msg_num_lines;
|
||||
}
|
||||
geo->right_margin = grub_term_width (term)
|
||||
- geo->first_entry_x
|
||||
- geo->entry_width - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
menu_text_print_timeout (int timeout, void *dataptr)
|
||||
{
|
||||
struct menu_viewer_data *data = dataptr;
|
||||
char *msg_translated = 0;
|
||||
|
||||
grub_term_gotoxy (data->term,
|
||||
(struct grub_term_coordinate) { 0, data->geo.timeout_y });
|
||||
|
||||
if (data->timeout_msg == TIMEOUT_TERSE
|
||||
|| data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN)
|
||||
msg_translated = grub_xasprintf (_("%ds"), timeout);
|
||||
else
|
||||
msg_translated = grub_xasprintf (_("The highlighted entry will be executed automatically in %ds."), timeout);
|
||||
if (!msg_translated)
|
||||
{
|
||||
grub_print_error ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->timeout_msg == TIMEOUT_UNKNOWN)
|
||||
{
|
||||
data->timeout_msg = grub_print_message_indented_real (msg_translated,
|
||||
3, 1, data->term, 1)
|
||||
<= data->geo.timeout_lines ? TIMEOUT_NORMAL : TIMEOUT_TERSE;
|
||||
if (data->timeout_msg == TIMEOUT_TERSE)
|
||||
{
|
||||
grub_free (msg_translated);
|
||||
msg_translated = grub_xasprintf (_("%ds"), timeout);
|
||||
if (grub_term_width (data->term) < 10)
|
||||
data->timeout_msg = TIMEOUT_TERSE_NO_MARGIN;
|
||||
}
|
||||
}
|
||||
|
||||
grub_print_message_indented (msg_translated,
|
||||
data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN ? 0 : 3,
|
||||
data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN ? 0 : 1,
|
||||
data->term);
|
||||
grub_free (msg_translated);
|
||||
|
||||
grub_term_gotoxy (data->term,
|
||||
(struct grub_term_coordinate) {
|
||||
grub_term_cursor_x (&data->geo),
|
||||
data->geo.first_entry_y + data->offset });
|
||||
grub_term_refresh (data->term);
|
||||
}
|
||||
|
||||
static void
|
||||
menu_text_set_chosen_entry (int entry, void *dataptr)
|
||||
{
|
||||
struct menu_viewer_data *data = dataptr;
|
||||
int oldoffset = data->offset;
|
||||
int complete_redraw = 0;
|
||||
|
||||
data->offset = entry - data->first;
|
||||
if (data->offset > data->geo.num_entries - 1)
|
||||
{
|
||||
data->first = entry - (data->geo.num_entries - 1);
|
||||
data->offset = data->geo.num_entries - 1;
|
||||
complete_redraw = 1;
|
||||
}
|
||||
if (data->offset < 0)
|
||||
{
|
||||
data->offset = 0;
|
||||
data->first = entry;
|
||||
complete_redraw = 1;
|
||||
}
|
||||
if (complete_redraw)
|
||||
print_entries (data->menu, data);
|
||||
else
|
||||
{
|
||||
print_entry (data->geo.first_entry_y + oldoffset, 0,
|
||||
grub_menu_get_entry (data->menu, data->first + oldoffset),
|
||||
data);
|
||||
print_entry (data->geo.first_entry_y + data->offset, 1,
|
||||
grub_menu_get_entry (data->menu, data->first + data->offset),
|
||||
data);
|
||||
}
|
||||
grub_term_refresh (data->term);
|
||||
}
|
||||
|
||||
static void
|
||||
menu_text_fini (void *dataptr)
|
||||
{
|
||||
struct menu_viewer_data *data = dataptr;
|
||||
|
||||
grub_term_setcursor (data->term, 1);
|
||||
grub_term_cls (data->term);
|
||||
grub_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
menu_text_clear_timeout (void *dataptr)
|
||||
{
|
||||
struct menu_viewer_data *data = dataptr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < data->geo.timeout_lines;i++)
|
||||
{
|
||||
grub_term_gotoxy (data->term, (struct grub_term_coordinate) {
|
||||
0, data->geo.timeout_y + i });
|
||||
grub_print_spaces (data->term, grub_term_width (data->term) - 1);
|
||||
}
|
||||
if (data->geo.num_entries <= 5 && !data->geo.border)
|
||||
{
|
||||
grub_term_gotoxy (data->term,
|
||||
(struct grub_term_coordinate) {
|
||||
data->geo.first_entry_x + data->geo.entry_width
|
||||
+ data->geo.border + 1,
|
||||
data->geo.first_entry_y + data->geo.num_entries - 1
|
||||
});
|
||||
grub_putcode (' ', data->term);
|
||||
|
||||
data->geo.timeout_lines = 0;
|
||||
data->geo.num_entries++;
|
||||
print_entries (data->menu, data);
|
||||
}
|
||||
grub_term_gotoxy (data->term,
|
||||
(struct grub_term_coordinate) {
|
||||
grub_term_cursor_x (&data->geo),
|
||||
data->geo.first_entry_y + data->offset });
|
||||
grub_term_refresh (data->term);
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_menu_try_text (struct grub_term_output *term,
|
||||
int entry, grub_menu_t menu, int nested)
|
||||
{
|
||||
struct menu_viewer_data *data;
|
||||
struct grub_menu_viewer *instance;
|
||||
|
||||
instance = grub_zalloc (sizeof (*instance));
|
||||
if (!instance)
|
||||
return grub_errno;
|
||||
|
||||
data = grub_zalloc (sizeof (*data));
|
||||
if (!data)
|
||||
{
|
||||
grub_free (instance);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
data->term = term;
|
||||
instance->data = data;
|
||||
instance->set_chosen_entry = menu_text_set_chosen_entry;
|
||||
instance->print_timeout = menu_text_print_timeout;
|
||||
instance->clear_timeout = menu_text_clear_timeout;
|
||||
instance->fini = menu_text_fini;
|
||||
|
||||
data->menu = menu;
|
||||
|
||||
data->offset = entry;
|
||||
data->first = 0;
|
||||
|
||||
grub_term_setcursor (data->term, 0);
|
||||
grub_menu_init_page (nested, 0, &data->geo, data->term);
|
||||
|
||||
if (data->offset > data->geo.num_entries - 1)
|
||||
{
|
||||
data->first = data->offset - (data->geo.num_entries - 1);
|
||||
data->offset = data->geo.num_entries - 1;
|
||||
}
|
||||
|
||||
print_entries (menu, data);
|
||||
grub_term_refresh (data->term);
|
||||
grub_menu_register_viewer (instance);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
194
GRUB2/MOD_SRC/grub-2.04/grub-core/normal/misc.c
Normal file
194
GRUB2/MOD_SRC/grub-2.04/grub-core/normal/misc.c
Normal file
@@ -0,0 +1,194 @@
|
||||
/* misc.c - miscellaneous functions */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/normal.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/fs.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/partition.h>
|
||||
|
||||
static const char *grub_human_sizes[3][6] =
|
||||
{
|
||||
/* This algorithm in reality would work only up to (2^64) / 100 B = 81 PiB.
|
||||
Put here all possible suffixes it can produce so no array bounds check
|
||||
is needed.
|
||||
*/
|
||||
/* TRANSLATORS: that's the list of binary unit prefixes. */
|
||||
{ N_("B"), N_("KiB"), N_("MiB"), N_("GiB"), N_("TiB"), N_("PiB")},
|
||||
/* TRANSLATORS: that's the list of binary unit prefixes. */
|
||||
{ "", N_("KB"), N_("MB"), N_("GB"), N_("TB"), N_("PB") },
|
||||
/* TRANSLATORS: that's the list of binary unit prefixes. */
|
||||
{ N_("B/s"), N_("KiB/s"), N_("MiB/s"), N_("GiB/s"), N_("TiB/s"), N_("PiB/s"), },
|
||||
};
|
||||
|
||||
const char *
|
||||
grub_get_human_size (grub_uint64_t size, enum grub_human_size_type type)
|
||||
{
|
||||
grub_uint64_t fsize;
|
||||
unsigned units = 0;
|
||||
static char buf[30];
|
||||
const char *umsg;
|
||||
|
||||
if (type != GRUB_HUMAN_SIZE_SPEED)
|
||||
fsize = size * 100ULL;
|
||||
else
|
||||
fsize = size;
|
||||
|
||||
/* Since 2^64 / 1024^5 < 102400, this can give at most 5 iterations.
|
||||
So units <=5, so impossible to go past the end of array.
|
||||
*/
|
||||
while (fsize >= 102400)
|
||||
{
|
||||
fsize = (fsize + 512) / 1024;
|
||||
units++;
|
||||
}
|
||||
|
||||
umsg = _(grub_human_sizes[type][units]);
|
||||
|
||||
if (units || type == GRUB_HUMAN_SIZE_SPEED)
|
||||
{
|
||||
grub_uint64_t whole, fraction;
|
||||
|
||||
whole = grub_divmod64 (fsize, 100, &fraction);
|
||||
grub_snprintf (buf, sizeof (buf),
|
||||
"%" PRIuGRUB_UINT64_T
|
||||
".%02" PRIuGRUB_UINT64_T "%s", whole, fraction,
|
||||
umsg);
|
||||
}
|
||||
else
|
||||
grub_snprintf (buf, sizeof (buf), "%llu%s", (unsigned long long) size,
|
||||
umsg);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Print the information on the device NAME. */
|
||||
grub_err_t
|
||||
grub_normal_print_device_info (const char *name)
|
||||
{
|
||||
grub_device_t dev;
|
||||
char *p;
|
||||
|
||||
p = grub_strchr (name, ',');
|
||||
if (p)
|
||||
{
|
||||
grub_xputs ("\t");
|
||||
grub_printf_ (N_("Partition %s:"), name);
|
||||
grub_xputs (" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_printf_ (N_("Device %s:"), name);
|
||||
grub_xputs (" ");
|
||||
}
|
||||
|
||||
dev = grub_device_open (name);
|
||||
if (! dev)
|
||||
grub_printf ("%s", _("Filesystem cannot be accessed"));
|
||||
else if (dev->disk)
|
||||
{
|
||||
grub_fs_t fs;
|
||||
|
||||
fs = grub_fs_probe (dev);
|
||||
/* Ignore all errors. */
|
||||
grub_errno = 0;
|
||||
|
||||
if (fs)
|
||||
{
|
||||
const char *fsname = fs->name;
|
||||
if (grub_strcmp (fsname, "ext2") == 0)
|
||||
fsname = "ext*";
|
||||
grub_printf_ (N_("Filesystem type %s"), fsname);
|
||||
if (fs->fs_label)
|
||||
{
|
||||
char *label;
|
||||
(fs->fs_label) (dev, &label);
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
{
|
||||
if (label && grub_strlen (label))
|
||||
{
|
||||
grub_xputs (" ");
|
||||
grub_printf_ (N_("- Label `%s'"), label);
|
||||
}
|
||||
grub_free (label);
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (fs->fs_mtime)
|
||||
{
|
||||
grub_int32_t tm;
|
||||
struct grub_datetime datetime;
|
||||
(fs->fs_mtime) (dev, &tm);
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
{
|
||||
grub_unixtime2datetime (tm, &datetime);
|
||||
grub_xputs (" ");
|
||||
/* TRANSLATORS: Arguments are year, month, day, hour, minute,
|
||||
second, day of the week (translated). */
|
||||
grub_printf_ (N_("- Last modification time %d-%02d-%02d "
|
||||
"%02d:%02d:%02d %s"),
|
||||
datetime.year, datetime.month, datetime.day,
|
||||
datetime.hour, datetime.minute, datetime.second,
|
||||
grub_get_weekday_name (&datetime));
|
||||
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (fs->fs_uuid)
|
||||
{
|
||||
char *uuid;
|
||||
(fs->fs_uuid) (dev, &uuid);
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
{
|
||||
if (uuid && grub_strlen (uuid))
|
||||
grub_printf (", UUID %s", uuid);
|
||||
grub_free (uuid);
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
grub_printf ("%s", _("No known filesystem detected"));
|
||||
|
||||
if (dev->disk->partition)
|
||||
grub_printf (_(" - Partition start at %llu%sKiB"),
|
||||
(unsigned long long) (grub_partition_get_start (dev->disk->partition) >> 1),
|
||||
(grub_partition_get_start (dev->disk->partition) & 1) ? ".5" : "" );
|
||||
else
|
||||
grub_printf_ (N_(" - Sector size %uB"), 1 << dev->disk->log_sector_size);
|
||||
if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN)
|
||||
grub_puts_ (N_(" - Total size unknown"));
|
||||
else
|
||||
grub_printf (_(" - Total size %llu%sKiB"),
|
||||
(unsigned long long) (grub_disk_get_size (dev->disk) >> 1),
|
||||
/* TRANSLATORS: Replace dot with appropriate decimal separator for
|
||||
your language. */
|
||||
(grub_disk_get_size (dev->disk) & 1) ? _(".5") : "");
|
||||
}
|
||||
|
||||
if (dev)
|
||||
grub_device_close (dev);
|
||||
|
||||
grub_xputs ("\n");
|
||||
return grub_errno;
|
||||
}
|
@@ -49,7 +49,7 @@ initrd_info *g_initrd_img_list = NULL;
|
||||
initrd_info *g_initrd_img_tail = NULL;
|
||||
int g_initrd_img_count = 0;
|
||||
int g_valid_initrd_count = 0;
|
||||
|
||||
int g_filt_dot_underscore_file = 0;
|
||||
static grub_file_t g_old_file;
|
||||
|
||||
char g_img_swap_tmp_buf[1024];
|
||||
@@ -618,6 +618,11 @@ static int ventoy_img_name_valid(const char *filename, grub_size_t namelen)
|
||||
{
|
||||
grub_size_t i;
|
||||
|
||||
if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < namelen; i++)
|
||||
{
|
||||
if (filename[i] == ' ' || filename[i] == '\t')
|
||||
@@ -938,6 +943,7 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
||||
grub_device_t dev = NULL;
|
||||
img_info *cur = NULL;
|
||||
img_info *tail = NULL;
|
||||
const char *strdata = NULL;
|
||||
char *device_name = NULL;
|
||||
char buf[32];
|
||||
img_iterator_node *node = NULL;
|
||||
@@ -955,6 +961,12 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
||||
return grub_error(GRUB_ERR_BAD_ARGUMENT, "Must clear image before list");
|
||||
}
|
||||
|
||||
strdata = ventoy_get_env("VTOY_FILT_DOT_UNDERSCORE_FILE");
|
||||
if (strdata && strdata[0] == '1' && strdata[1] == 0)
|
||||
{
|
||||
g_filt_dot_underscore_file = 1;
|
||||
}
|
||||
|
||||
device_name = grub_file_get_device_name(args[0]);
|
||||
if (!device_name)
|
||||
{
|
@@ -40,6 +40,34 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static install_template *g_install_template_head = NULL;
|
||||
|
||||
static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
VTOY_JSON *pNode = NULL;
|
||||
VTOY_JSON *pChild = NULL;
|
||||
|
||||
(void)isodisk;
|
||||
|
||||
if (json->enDataType != JSON_TYPE_ARRAY)
|
||||
{
|
||||
debug("Not array %d\n", json->enDataType);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
|
||||
{
|
||||
if (pNode->enDataType == JSON_TYPE_OBJECT)
|
||||
{
|
||||
pChild = pNode->pstChild;
|
||||
if (pChild->enDataType == JSON_TYPE_STRING && pChild->pcName && pChild->unData.pcStrVal)
|
||||
{
|
||||
ventoy_set_env(pChild->pcName, pChild->unData.pcStrVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
const char *value;
|
||||
@@ -136,6 +164,7 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk
|
||||
|
||||
static plugin_entry g_plugin_entries[] =
|
||||
{
|
||||
{ "control", ventoy_plugin_control_entry },
|
||||
{ "theme", ventoy_plugin_theme_entry },
|
||||
{ "auto_install", ventoy_plugin_auto_install_entry },
|
||||
};
|
43
GRUB2/MOD_SRC/grub-2.04/install.sh
Normal file
43
GRUB2/MOD_SRC/grub-2.04/install.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
VT_DIR=$PWD/../../..
|
||||
|
||||
rm -rf $VT_DIR/GRUB2/INSTALL
|
||||
rm -rf $VT_DIR/GRUB2/PXE
|
||||
mkdir -p $VT_DIR/GRUB2/INSTALL
|
||||
mkdir -p $VT_DIR/GRUB2/PXE
|
||||
|
||||
make install
|
||||
|
||||
PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/
|
||||
|
||||
net_modules_legacy="net tftp http"
|
||||
all_modules_legacy="date drivemap blocklist ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu"
|
||||
|
||||
net_modules_uefi="efinet net tftp http"
|
||||
all_modules_uefi="blocklist ventoy test ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu"
|
||||
|
||||
|
||||
if [ "$1" = "uefi" ]; then
|
||||
all_modules="$net_modules_uefi $all_modules_uefi"
|
||||
grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,msdos2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos'
|
||||
else
|
||||
all_modules="$net_modules_legacy $all_modules_legacy"
|
||||
grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,msdos2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk'
|
||||
fi
|
||||
|
||||
grub-mknetdir --modules="$all_modules" --net-directory=$VT_DIR/GRUB2/PXE --subdir=grub2 --locales=en@quot || exit 1
|
||||
|
||||
if [ "$1" = "uefi" ]; then
|
||||
rm -f $VT_DIR/GRUB2/NBP/core.efi
|
||||
cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1
|
||||
|
||||
rm -f $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod
|
||||
cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/normal.mod $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod || exit 1
|
||||
else
|
||||
rm -f $VT_DIR/GRUB2/NBP/core.0
|
||||
cp -a $VT_DIR/GRUB2/PXE/grub2/i386-pc/core.0 $VT_DIR/GRUB2/NBP/core.0 || exit 1
|
||||
|
||||
rm -f $VT_DIR/INSTALL/grub/i386-pc/boot.img
|
||||
cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/boot.img $VT_DIR/INSTALL/grub/i386-pc/boot.img || exit 1
|
||||
fi
|
@@ -1,14 +0,0 @@
|
||||
|
||||
========== About Source Code =============
|
||||
Ventoy use grub-2.04, so I only put the added and modified source code here.
|
||||
|
||||
You can download grub-2.04 source code from this site:
|
||||
https://ftp.gnu.org/gnu/grub/
|
||||
|
||||
Just merge the code here with the original code of grub-2.04
|
||||
|
||||
|
||||
========== Build =============
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
35
GRUB2/buildgrub.sh
Normal file
35
GRUB2/buildgrub.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
VT_GRUB_DIR=$PWD
|
||||
|
||||
rm -rf INSTALL
|
||||
rm -rf SRC
|
||||
rm -rf NBP
|
||||
rm -rf PXE
|
||||
|
||||
mkdir SRC
|
||||
mkdir NBP
|
||||
mkdir PXE
|
||||
|
||||
tar -xvf grub-2.04.tar.xz -C ./SRC/
|
||||
|
||||
/bin/cp -a ./MOD_SRC/grub-2.04 ./SRC/
|
||||
|
||||
cd ./SRC/grub-2.04
|
||||
|
||||
# build for Legacy BIOS
|
||||
./autogen.sh
|
||||
./configure --prefix=$VT_GRUB_DIR/INSTALL/
|
||||
make -j 16
|
||||
sh install.sh
|
||||
|
||||
# build for UEFI
|
||||
make distclean
|
||||
./autogen.sh
|
||||
./configure --with-platform=efi --prefix=$VT_GRUB_DIR/INSTALL/
|
||||
make -j 16
|
||||
sh install.sh uefi
|
||||
|
||||
|
||||
cd ../../
|
||||
|
Reference in New Issue
Block a user