Files
webmin/grub2/edit_theme.cgi

210 lines
6.2 KiB
Perl
Executable File

#!/usr/local/bin/perl
# Show a form for editing GRUB 2 theme and appearance settings.
use strict;
use warnings;
require './grub2-lib.pl'; ## no critic
our (%text);
&ReadParse();
&error_setup($text{'theme_err'});
my %access = &get_module_acl();
&error("$text{'eacl_np'} $text{'eacl_pedit'}") if (!$access{'edit'});
my $parsed = &read_grub_defaults();
my $values = $parsed->{'values'};
my $current_theme = &field_value($values->{'GRUB_THEME'});
my $theme_action = $current_theme ne '' ? 'keep' : 'clear';
&ui_print_header(undef, $text{'theme_title'}, "", "theme_mode");
# Theme source is only used when the action selector requests installation.
print &ui_form_start("save_theme.cgi", "post");
print &ui_table_start($text{'defaults_theme_header'}, "width=100%", 2);
print &ui_table_row(
&hlink($text{'defaults_theme_current'}, "theme"),
$current_theme ne '' ?
&ui_tag('tt', &html_escape($current_theme)) :
$text{'defaults_theme_none'}
);
print &ui_table_row(
&hlink($text{'defaults_theme_action'}, "theme_mode"),
&ui_select("theme_mode", $theme_action,
[
[ "keep", $text{'defaults_theme_keep'} ],
[ "install", $text{'defaults_theme_install'} ],
[ "clear", $text{'defaults_theme_clear'} ],
])
);
print &ui_table_row(
&hlink($text{'defaults_theme_source'}, "theme_source"),
&ui_textbox("theme_source", "", 60).
" ".&file_chooser_button("theme_source").
&ui_tag('div', &ui_note($text{'defaults_theme_note'}, 0))
);
print &ui_table_row(
&hlink($text{'defaults_terminal_output'}, "terminal_output"),
&ui_select("terminal_output",
&field_value($values->{'GRUB_TERMINAL_OUTPUT'}),
[
[ "", $text{'defaults_keep'} ],
[ "console", $text{'defaults_terminal_console'} ],
[ "gfxterm", $text{'defaults_terminal_gfxterm'} ],
[ "gfxterm console",
$text{'defaults_terminal_gfxterm_console'} ],
[ "serial", $text{'defaults_terminal_serial'} ],
])
);
print &ui_table_row(
&hlink($text{'defaults_gfxmode'}, "gfxmode"),
&gfxmode_select(&field_value($values->{'GRUB_GFXMODE'}))
);
print &ui_table_row(
&hlink($text{'defaults_background'}, "background"),
&ui_textbox("background", &field_value($values->{'GRUB_BACKGROUND'}), 60).
" ".&file_chooser_button("background").
&ui_tag('div', &ui_note($text{'defaults_background_note'}, 0))
);
print &ui_table_row(
&hlink($text{'defaults_color_normal'}, "color_normal"),
&color_pair_select("color_normal", $values->{'GRUB_COLOR_NORMAL'},
"white", "black")
);
print &ui_table_row(
&hlink($text{'defaults_color_highlight'}, "color_highlight"),
&color_pair_select("color_highlight",
$values->{'GRUB_COLOR_HIGHLIGHT'},
"black", "light-gray")
);
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'save'} ] ]);
print &color_mode_script();
&ui_print_footer("index.cgi", $text{'index_return'});
# color_pair_select(name, value, default-foreground, default-background)
# Returns foreground/background selectors for GRUB menu colors.
sub color_pair_select
{
my ($name, $value, $default_fg, $default_bg) = @_;
my ($fg, $bg) = ($default_fg, $default_bg);
my $mode = "default";
if (defined($value) && $value =~ /^([^\/]+)\/([^\/]+)\z/) {
# Existing GRUB colors are stored as foreground/background pairs.
($fg, $bg) = ($1, $2);
$mode = "set";
}
return &ui_select($name."_mode", $mode, [
[ "default", $text{'defaults_color_default'} ],
[ "set", $text{'defaults_color_custom'} ],
]).
&ui_tag('span',
" ".&html_escape($text{'defaults_color_text'})." ".
&ui_select($name."_fg", $fg, &color_options())." ".
" ".&html_escape($text{'defaults_color_background'}).
" ".&ui_select($name."_bg", $bg, &color_options()),
{
'id' => $name."_custom_colors",
'style' => 'white-space: nowrap; visibility: '.
($mode eq 'set' ? 'visible' : 'hidden').';',
});
}
# color_mode_script()
# Shows foreground/background selectors only for custom color pairs.
sub color_mode_script
{
return &ui_tag('script', <<'EOF', { 'type' => 'application/javascript' });
function grub2_color_mode_select(name) {
// Theme reloads may replace IDs; fall back to the stable field name.
return document.getElementById(name + '_mode') ||
document.querySelector('select[name="' + name + '_mode"]');
}
function grub2_color_mode_changed(name) {
const mode = grub2_color_mode_select(name);
const custom = document.getElementById(name + '_custom_colors');
if (!mode || !custom) {
return;
}
// Visibility avoids layout jumps when a custom color pair is enabled.
custom.style.visibility = mode.value === 'set' ? 'visible' : 'hidden';
}
function grub2_color_modes_refresh() {
grub2_color_mode_changed('color_normal');
grub2_color_mode_changed('color_highlight');
}
document.addEventListener('change', function(event) {
const target = event.target;
if (!target || !target.name) {
return;
}
if (target.name === 'color_normal_mode') {
grub2_color_mode_changed('color_normal');
}
else if (target.name === 'color_highlight_mode') {
grub2_color_mode_changed('color_highlight');
}
});
grub2_color_modes_refresh();
document.addEventListener('DOMContentLoaded', grub2_color_modes_refresh);
if (window.MutationObserver && document.body) {
// Re-apply after theme JavaScript re-renders form controls.
new MutationObserver(grub2_color_modes_refresh).observe(document.body, {
childList: true,
subtree: true
});
}
EOF
}
# gfxmode_select(value)
# Returns a dropdown of common GRUB graphical resolutions.
sub gfxmode_select
{
my ($value) = @_;
return &ui_select("gfxmode", $value, &gfxmode_options(), undef, undef, 1);
}
# gfxmode_options()
# Returns common GRUB graphical resolution choices.
sub gfxmode_options
{
return [
[ "", $text{'defaults_gfxmode_default'} ],
[ "auto", $text{'defaults_gfxmode_auto'} ],
map { [ $_, $_ ] } qw(
640x480
800x600
1024x768
1280x720
1280x800
1366x768
1440x900
1600x900
1680x1050
1920x1080
1920x1200
2560x1440
3840x2160
),
];
}
# color_options()
# Returns GRUB color choices.
sub color_options
{
return [
map { [ $_, $text{'color_'.$_} || $_ ] } &grub2_color_names()
];
}
# field_value(value, [default])
# Returns a form value without treating the string 0 as empty.
sub field_value
{
my ($value, $default) = @_;
return defined($value) ? $value : ($default || '');
}