Add muli-languages support for Ventoy menu.

F5 ---> Menu Language Select
Language files are in INSTALL/grub/menu/ directory.
This commit is contained in:
longpanda
2022-12-02 20:35:59 +08:00
parent 3be4aacd78
commit 511b8091eb
26 changed files with 537 additions and 100 deletions

View File

@@ -25,6 +25,10 @@
#include <grub/i18n.h>
#include <grub/normal.h>
typedef const char * (*get_vmenu_title_pf)(const char *vMenu);
static get_vmenu_title_pf g_pfvmenu_title = NULL;
static const struct grub_arg_option options[] =
{
{"class", 1, GRUB_ARG_OPTION_REPEATABLE,
@@ -86,6 +90,8 @@ grub_normal_add_menu_entry (int argc, const char **args,
char *menu_title = NULL;
char *menu_sourcecode = NULL;
char *menu_id = NULL;
const char *vmenu = NULL;
const char *vaddr = NULL;
struct grub_menu_entry_class *menu_classes = NULL;
grub_menu_t menu;
@@ -145,7 +151,17 @@ grub_normal_add_menu_entry (int argc, const char **args,
goto fail;
}
menu_title = grub_strdup (args[0]);
if (!g_pfvmenu_title) {
vaddr = grub_env_get("VTOY_VMENU_FUNC_ADDR");
if (vaddr)
g_pfvmenu_title = (get_vmenu_title_pf)(unsigned long)grub_strtoul(vaddr, NULL, 16);
}
if (g_pfvmenu_title && grub_strncmp(args[0], "@VTMENU_", 8) == 0)
vmenu = g_pfvmenu_title(args[0] + 1);
menu_title = grub_strdup (vmenu ? vmenu : args[0]);
if (! menu_title)
goto fail;

View File

@@ -31,6 +31,7 @@ extern int g_ventoy_iso_raw;
extern int g_ventoy_grub2_mode;
extern int g_ventoy_wimboot_mode;
extern int g_ventoy_iso_uefi_drv;
extern char g_ventoy_hotkey_tip[256];
static const char *align_options[] =
{
@@ -230,10 +231,7 @@ label_set_property (void *vself, const char *name, const char *value)
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 = _(" ");
}
value = g_ventoy_hotkey_tip;
}
self->template = grub_strdup (value);

View File

@@ -50,6 +50,8 @@ int g_ventoy_menu_esc = 0;
int g_ventoy_fn_mutex = 0;
int g_ventoy_secondary_menu_on = 0;
int g_ventoy_terminal_output = 0;
char g_ventoy_hotkey_tip[256];
int g_ventoy_virt_esc = 0;
#define VTOY_COMM_HOTKEY(cmdkey) \
if (0 == g_ventoy_fn_mutex && 0 == g_ventoy_secondary_menu_on) { \
@@ -796,7 +798,12 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
return default_entry;
}
c = grub_getkey_noblock ();
if (g_ventoy_virt_esc > 0) {
c = GRUB_TERM_ESC;
g_ventoy_virt_esc--;
} else {
c = grub_getkey_noblock ();
}
/* Negative values are returned on error. */
if ((c != GRUB_TERM_NO_KEY) && (c > 0))

View File

@@ -31,6 +31,8 @@
static grub_uint8_t grub_color_menu_normal;
static grub_uint8_t grub_color_menu_highlight;
extern char g_ventoy_hotkey_tip[256];
struct menu_viewer_data
{
int first, offset;
@@ -204,7 +206,7 @@ command-line or ESC to discard edits and return to the GRUB menu."),
ret += grub_print_message_indented_real(szLine, 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"),
ret += grub_print_message_indented_real(g_ventoy_hotkey_tip,
3, 6, term, dry_run);
}
}

View File

@@ -616,13 +616,15 @@ grub_err_t ventoy_cmd_browser_disk(grub_extcmd_context_t ctxt, int argc, char **
if (g_tree_view_menu_style == 0)
{
browser_ssprintf(&mbuf, "menuentry \"%-10s [Return]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n", "<--");
browser_ssprintf(&mbuf, "menuentry \"%-10s [%s]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n", "<--",
ventoy_get_vmenu_title("VTMENU_BROWER_RETURN"));
}
else
{
browser_ssprintf(&mbuf, "menuentry \"[Return]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n");
browser_ssprintf(&mbuf, "menuentry \"[%s]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n",
ventoy_get_vmenu_title("VTMENU_BROWER_RETURN"));
}
grub_disk_dev_iterate(ventoy_browser_iterate_disk, &mbuf);

View File

@@ -2346,16 +2346,16 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
if (g_tree_view_menu_style == 0)
{
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
"menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
"menuentry \"%-10s [%s]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n"
"}\n", "<--");
"}\n", "<--", ventoy_get_vmenu_title("VTMENU_RET_TO_LISTVIEW"));
}
else
{
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
"menuentry \"[Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
"menuentry \"[%s]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n"
"}\n");
"}\n", ventoy_get_vmenu_title("VTMENU_RET_TO_LISTVIEW"));
}
}
@@ -2934,9 +2934,9 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
if (g_default_menu_mode == 1)
{
vtoy_ssprintf(g_list_script_buf, g_list_script_pos,
"menuentry \"%s [Return to TreeView]\" --class=\"vtoyret\" VTOY_RET {\n "
"menuentry \"%s [%s]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n"
"}\n", "<--");
"}\n", "<--", ventoy_get_vmenu_title("VTMENU_RET_TO_TREEVIEW"));
}
for (cur = g_ventoy_img_list; cur; cur = cur->next)
@@ -3705,13 +3705,14 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar
vtoy_ssprintf(buf, pos, "set timeout=%d\n", node->timeout);
}
vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" --class=\"sel_auto_install\" {\n"
vtoy_ssprintf(buf, pos, "menuentry \"@VTMENU_NO_AUTOINS_SCRIPT\" --class=\"sel_auto_install\" {\n"
" echo %s\n}\n", "");
for (i = 0; i < node->templatenum; i++)
{
vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" --class=\"sel_auto_install\" {\n"
vtoy_ssprintf(buf, pos, "menuentry \"%s %s\" --class=\"sel_auto_install\" {\n"
" echo \"\"\n}\n",
ventoy_get_vmenu_title("VTMENU_AUTOINS_USE"),
node->templatepath[i].path);
}
@@ -3811,13 +3812,14 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg
vtoy_ssprintf(buf, pos, "set timeout=%d\n", node->timeout);
}
vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" --class=\"sel_persistence\" {\n"
vtoy_ssprintf(buf, pos, "menuentry \"@VTMENU_NO_PERSISTENCE\" --class=\"sel_persistence\" {\n"
" echo %s\n}\n", "");
for (i = 0; i < node->backendnum; i++)
{
vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" --class=\"sel_persistence\" {\n"
vtoy_ssprintf(buf, pos, "menuentry \"%s %s\" --class=\"sel_persistence\" {\n"
" echo \"\"\n}\n",
ventoy_get_vmenu_title("VTMENU_PERSIST_USE"),
node->backendpath[i].path);
}
@@ -6073,26 +6075,26 @@ static grub_err_t ventoy_cmd_show_secondary_menu(grub_extcmd_context_t ctxt, int
fsize = grub_strtoull(args[2], NULL, 10);
vtoy_dummy_menuentry(cmd, pos, len, "Boot in normal mode", "second_normal"); seldata[n++] = 1;
vtoy_dummy_menuentry(cmd, pos, len, "@VTMENU_NORMAL_MODE", "second_normal"); seldata[n++] = 1;
if (grub_strcmp(args[1], "Unix") != 0)
{
if (grub_strcmp(args[1], "Windows") == 0)
{
vtoy_dummy_menuentry(cmd, pos, len, "Boot in wimboot mode", "second_wimboot"); seldata[n++] = 2;
vtoy_dummy_menuentry(cmd, pos, len, "@VTMENU_WIMBOOT_MODE", "second_wimboot"); seldata[n++] = 2;
}
else
{
vtoy_dummy_menuentry(cmd, pos, len, "Boot in grub2 mode", "second_grub2"); seldata[n++] = 3;
vtoy_dummy_menuentry(cmd, pos, len, "@VTMENU_GRUB2_MODE", "second_grub2"); seldata[n++] = 3;
}
if (fsize <= VTOY_SIZE_1GB)
{
vtoy_dummy_menuentry(cmd, pos, len, "Boot in memdisk mode", "second_memdisk"); seldata[n++] = 4;
vtoy_dummy_menuentry(cmd, pos, len, "@VTMENU_MEMDISK_MODE", "second_memdisk"); seldata[n++] = 4;
}
}
vtoy_dummy_menuentry(cmd, pos, len, "File checksum", "second_checksum"); seldata[n++] = 5;
vtoy_dummy_menuentry(cmd, pos, len, "@VTMENU_FILE_CHKSUM", "second_checksum"); seldata[n++] = 5;
do {
g_ventoy_menu_esc = 1;
@@ -6175,6 +6177,15 @@ static grub_err_t ventoy_cmd_fs_ignore_case(grub_extcmd_context_t ctxt, int argc
return 0;
}
static grub_err_t ventoy_cmd_load_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args)
{
(void)ctxt;
(void)argc;
ventoy_plugin_load_menu_lang(args[0]);
VENTOY_CMD_RETURN(0);
}
int ventoy_env_init(void)
{
int i;
@@ -6216,6 +6227,10 @@ int ventoy_env_init(void)
grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_chain_file_read);
grub_env_set("vtoy_chain_file_read", buf);
grub_env_export("vtoy_chain_file_read");
grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_get_vmenu_title);
grub_env_set("VTOY_VMENU_FUNC_ADDR", buf);
grub_env_export("VTOY_VMENU_FUNC_ADDR");
return 0;
}
@@ -6383,6 +6398,8 @@ static cmd_para ventoy_cmds[] =
{ "vt_systemd_menu", ventoy_cmd_linux_systemd_menu, 0, NULL, "", "", NULL },
{ "vt_limine_menu", ventoy_cmd_linux_limine_menu, 0, NULL, "", "", NULL },
{ "vt_secondary_recover_mode", ventoy_cmd_secondary_recover_mode, 0, NULL, "", "", NULL },
{ "vt_load_menu_lang", ventoy_cmd_load_menu_lang, 0, NULL, "", "", NULL },
{ "vt_cur_menu_lang", ventoy_cmd_cur_menu_lang, 0, NULL, "", "", NULL },
};
int ventoy_register_all_cmd(void)

View File

@@ -1053,6 +1053,10 @@ extern int g_ventoy_case_insensitive;
extern int g_ventoy_fn_mutex;
extern grub_uint8_t g_ventoy_chain_type;
extern int g_vhdboot_enable;
extern int g_default_menu_mode;
extern char g_ventoy_hotkey_tip[256];
extern int g_ventoy_menu_refresh;
extern int g_ventoy_virt_esc;
#define VENTOY_IMG_WHITE_LIST 1
#define VENTOY_IMG_BLACK_LIST 2
@@ -1258,6 +1262,9 @@ grub_err_t ventoy_cmd_browser_disk(grub_extcmd_context_t ctxt, int argc, char **
int ventoy_get_fs_type(const char *fs);
int ventoy_img_name_valid(const char *filename, grub_size_t namelen);
void * ventoy_alloc_chain(grub_size_t size);
int ventoy_plugin_load_menu_lang(const char *lang);
const char *ventoy_get_vmenu_title(const char *vMenu);
grub_err_t ventoy_cmd_cur_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args);
#endif /* __VENTOY_DEF_H__ */

View File

@@ -56,12 +56,14 @@ static injection_config *g_injection_head = NULL;
static auto_memdisk *g_auto_memdisk_head = NULL;
static image_list *g_image_list_head = NULL;
static conf_replace *g_conf_replace_head = NULL;
static VTOY_JSON *g_menu_lang_json = NULL;
static int g_theme_id = 0;
static int g_theme_num = 0;
static theme_list *g_theme_head = NULL;
static int g_theme_random = vtoy_theme_random_boot_second;
static char g_theme_single_file[256];
static char g_cur_menu_language[32] = {0};
static int ventoy_plugin_is_parent(const char *pat, int patlen, const char *isopath)
{
@@ -2446,6 +2448,7 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a
int ret = 0;
int offset = 0;
char *buf = NULL;
const char *env = NULL;
grub_uint8_t *code = NULL;
grub_file_t file;
VTOY_JSON *json = NULL;
@@ -2539,6 +2542,9 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a
grub_env_unset("VTOY_MENU_TIP_ENABLE");
}
env = grub_env_get("VTOY_MENU_LANGUAGE");
ventoy_plugin_load_menu_lang(env ? env : "en_US");
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
@@ -3369,7 +3375,7 @@ grub_err_t ventoy_cmd_select_theme_cfg(grub_extcmd_context_t ctxt, int argc, cha
}
pos += grub_snprintf(buf + pos, bufsize - pos,
"menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {\n"
"menuentry '@VTMENU_RETURN_PREVIOUS' --class=vtoyret VTOY_RET {\n"
"echo 'Return ...'\n"
"}\n");
@@ -3467,3 +3473,87 @@ grub_err_t ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt, int argc, char
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
const char *ventoy_get_vmenu_title(const char *vMenu)
{
return vtoy_json_get_string_ex(g_menu_lang_json->pstChild, vMenu);
}
int ventoy_plugin_load_menu_lang(const char *lang)
{
int ret = 1;
grub_file_t file = NULL;
char *buf = NULL;
if (grub_strcmp(lang, g_cur_menu_language) == 0)
{
debug("Same menu lang %s\n", lang);
return 0;
}
grub_snprintf(g_cur_menu_language, sizeof(g_cur_menu_language), "%s", lang);
debug("Load menu lang %s\n", g_cur_menu_language);
if (g_menu_lang_json)
{
vtoy_json_destroy(g_menu_lang_json);
g_menu_lang_json = NULL;
}
g_menu_lang_json = vtoy_json_create();
if (!g_menu_lang_json)
{
goto end;
}
file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "(vt_menu_tarfs)/menu/%s.json", lang);
if (!file)
{
goto end;
}
buf = grub_malloc(file->size + 1);
if (!buf)
{
grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1));
goto end;
}
buf[file->size] = 0;
grub_file_read(file, buf, file->size);
vtoy_json_parse(g_menu_lang_json, buf);
if (g_default_menu_mode == 0)
{
grub_snprintf(g_ventoy_hotkey_tip, sizeof(g_ventoy_hotkey_tip), "%s", ventoy_get_vmenu_title("VTMENU_STR_HOTKEY_TREE"));
}
else
{
grub_snprintf(g_ventoy_hotkey_tip, sizeof(g_ventoy_hotkey_tip), "%s", ventoy_get_vmenu_title("VTMENU_STR_HOTKEY_LIST"));
}
g_ventoy_virt_esc = 2;
g_ventoy_menu_refresh = 1;
ret = 0;
end:
check_free(file, grub_file_close);
grub_check_free(buf);
return ret;
}
grub_err_t ventoy_cmd_cur_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args)
{
(void)ctxt;
(void)argc;
(void)args;
grub_printf("%s\n", g_cur_menu_language);
grub_printf("%s\n", g_ventoy_hotkey_tip);
grub_refresh();
VENTOY_CMD_RETURN(0);
}