#!/usr/bin/perl # DrakBoot # $Id$ # Copyright (C) 2001-2003 MandrakeSoft # Yves Duret, Thierry Vignaud # # This program 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 2, or (at your option) # any later version. # # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. use strict; use diagnostics; use lib qw(/usr/lib/libDrakX); use standalone; #- warning, standalone must be loaded very first, for 'explanations' use c; use common; use interactive; use any; use bootloader; use detect_devices; use fsedit; use fs; use Config; use POSIX; use Xconfig::various; use log; my $splash_working = 0; my $in = 'interactive'->vnew('su'); if (!$in->isa('interactive::gtk') || any { /^--boot$/ } @ARGV) { lilo_choice(); $in->exit(0); } require ugtk2; ugtk2->import(qw(:helpers :wrappers :create)); my $no_bootsplash; my $x_mode = Xconfig::various::runlevel() == 5; my $auto_mode = any::get_autologin(); my $lilogrub = bootloader::detect_bootloader(); my $w = ugtk2->new(N("Boot Style Configuration")); my $window = $w->{window}; $::main_window = $w->{rwindow} if !$::isEmbedded; $window->signal_connect(delete_event => sub { ugtk2->exit(0) }); unless ($::isEmbedded) { $window->set_border_width(2); ### menus definition # the menus are not shown but they provides shiny shortcut like C-q my @menu_items = ([ N("/_File"), undef, undef, undef, '<Branch>' ], [ N("/File/_Quit"), N("<control>Q"), sub { ugtk2->exit(0) }, undef, '<Item>' ], ); create_factory_menu($w->{rwindow}, @menu_items); ######### menus end } my $user_combo = new Gtk2::OptionMenu; $user_combo->set_popdown_strings(list_users()); $user_combo->entry->set_text($auto_mode->{autologin}) if $auto_mode->{autologin}; my $desktop_combo = new Gtk2::OptionMenu; $desktop_combo->set_popdown_strings(split(' ', `/usr/sbin/chksession -l`)); $desktop_combo->entry->set_text($auto_mode->{desktop}) if $auto_mode->{desktop}; my %themes = ('path' => '/usr/share/bootsplash/themes/', 'default' => 'Mandrake', 'def_thmb' => '/usr/share/libDrakX/pixmaps/nosplash_thumb.png', 'lilo' => {'file' => '/lilo/message', 'thumb' => '/lilo/thumb.png' }, 'boot' => {'path' => '/images/', #'thumb'=>'/images/thumb.png', }, ); my $cur_res = top(cat_('/etc/lilo.conf') =~ /[^#]*vga=(.*)/); #- verify that current resolution is ok if (member($cur_res, qw( 785 788 791 794))) { ($cur_res) = $bootloader::vga_modes{$cur_res} =~ /^([0-9x]+).*?$/; } else { $no_bootsplash = 1; #- we can't select any theme we're not in Framebuffer mode :-/ } #- and check that lilo is the correct loader $no_bootsplash ||= $lilogrub ne 'LILO'; $no_bootsplash = 0 if $::testing; my @thms; my @lilo_thms = if_(!$themes{default}, qw(default)); my @boot_thms = if_(!$themes{default}, qw(default)); chdir($themes{path}); #- we must change directory for correct @thms assignement foreach (all('.')) { if (-d $themes{path} . $_ && m/^[^.]/) { push @thms, $_; -f $themes{path} . $_ . $themes{lilo}{file} and push @lilo_thms, $_; -f $themes{path} . $_ . $themes{boot}{path} . "bootsplash-$cur_res.jpg" and push @boot_thms, $_; } # $_ eq $themes{'defaut'} and $default = $themes{'defaut'}; } my %combo = ('thms' => '', 'lilo' => '', 'boot' => ''); foreach (keys(%combo)) { $combo{$_} = gtkset_size_request(Gtk2::OptionMenu->new, 10, -1); } $combo{thms}->set_popdown_strings(@thms); $combo{lilo}->set_popdown_strings(@lilo_thms); $combo{boot}->set_popdown_strings(@boot_thms) if !$no_bootsplash; my $lilo_pixbuf; my $lilo_pic = gtkcreate_img($themes{def_thmb}); my $boot_pic = gtkcreate_img($themes{def_thmb}); my $thm_button = new Gtk2::Button(N("Install themes")); my $logo_thm = new Gtk2::CheckButton(N("Display theme\nunder console")); my $B_create = new Gtk2::Button(N("Create new theme")); my $keep_logo = 1; $logo_thm->set_active(1); $logo_thm->signal_connect(clicked => sub { invbool(\$keep_logo) }); $B_create->signal_connect(clicked => sub { system('/usr/sbin/draksplash '); }); #- ******** action to take on changing combos values $combo{thms}->entry->signal_connect(changed => sub { my $thm_txt = $combo{thms}->entry->get_text; $combo{lilo}->entry->set_text(member($thm_txt, @lilo_thms) ? $thm_txt : $themes{default} || 'default'); $combo{boot}->entry->set_text(member($thm_txt, @boot_thms) ? $thm_txt : $themes{default} || 'default'); }); $combo{lilo}->entry->signal_connect(changed => sub { my $new_file = $themes{path} . $combo{lilo}->entry->get_text . $themes{lilo}{thumb}; undef($lilo_pixbuf); $lilo_pixbuf = gtkcreate_pixbuf(-r $new_file ? $new_file : $themes{def_thmb}); $lilo_pixbuf = $lilo_pixbuf->scale_simple(155, 116, 'nearest'); $lilo_pic->set_from_pixbuf($lilo_pixbuf); }); $no_bootsplash == 0 and $combo{boot}->entry->signal_connect(changed => sub { my $img_file = $themes{path}.$combo{boot}->entry->get_text.$themes{boot}{path}."bootsplash-$cur_res.jpg"; $boot_pic = gtkcreate_img($img_file); }); $combo{thms}->entry->set_text($themes{default}); $thm_button->signal_connect('clicked', sub { my $error = 0; my $boot_conf_file = '/etc/sysconfig/bootsplash'; my $lilomsg = '/boot/message-graphic'; #lilo installation if (-f $themes{path}.$combo{lilo}->entry->get_text . $themes{lilo}{file}) { use MDK::Common::File; cp_af($lilomsg, "/boot/message-graphic.old"); #can't use this anymore or $in->ask_warn(N("Error"), N("unable to backup lilo message")); cp_af($themes{path} . $combo{lilo}->entry->get_text . $themes{lilo}{file}, $lilomsg); #can't use this anymore or $in->ask_warn(N("Error"), N("can't change lilo message")); } else { $error = 1; $in->ask_warn(N("Error"), N("Lilo message not found")); } #bootsplash install if ($::testing || -f $themes{path} . $combo{boot}->entry->get_text . $themes{boot}{path} . "bootsplash-$cur_res.jpg") { my $bootsplash_cont = "# -*- Mode: shell-script -*- # Specify here if you want add the splash logo to initrd when # generating an initrd. You can specify : # # SPLASH=no to don't have a splash screen # # SPLASH=auto to make autodetect the splash screen # # SPLASH=INT When Integer could be 800x600 1024x768 1280x1024 # SPLASH=$cur_res # Choose the themes. The should be based in # /usr/share/bootsplash/themes/ THEME=" . $combo{boot}->entry->get_text . " # Say yes here if you want to leave the logo on the console. # Three options : # # LOGO_CONSOLE=no don't display logo under console. # # LOGO_CONSOLE=yes display logo under console. # # LOGO_CONSOLE=theme leave the theme to decide. # LOGO_CONSOLE=" . ($keep_logo ? 'yes' : 'no') . "\n"; if (-f $boot_conf_file) { eval { output($boot_conf_file, $bootsplash_cont) }; $@ && $in->ask_warn(N("Error"), N("Can't write /etc/sysconfig/bootsplash.")); } else { $in->ask_warn(N("Error"), N("Can't write /etc/sysconfig/bootsplash\nFile not found.")); $error = 1; } } else { $in->ask_warn("Error", "BootSplash screen not found"); return; } #here is mkinitrd time if (!$error && !$::testing) { foreach (map { if_(m|^initrd-(.*)\.img|, $1) } all('/boot')) { if (system("mkinitrd -f /boot/initrd-$_.img $_")) { $in->ask_warn(N("Error"), N("Can't launch mkinitrd -f /boot/initrd-%s.img %s.", $_,$_)); $error = 1; } } } if (system('lilo')) { $in->ask_warn(N("Error"), N("Can't relaunch LiLo! Launch \"lilo\" as root in command line to complete LiLo theme installation.")); $error = 1; } $in->ask_warn($error ? N("Error") : N("Notice"), $error ? N("Theme installation failed!") : N("LiLo and Bootsplash themes installation successful")); }); my $x_box; gtkadd($window, gtkpack_(new Gtk2::VBox(0,0), #Splash Selector if_($splash_working, 0, gtkadd(my $thm_frame = new Gtk2::Frame(N("Splash selection")), gtkpack(gtkset_border_width(new Gtk2::HBox(0, 5), 5), gtkpack__(new Gtk2::VBox(0, 5), N("Themes"), $combo{thms}, N("\nSelect the theme for\nlilo and bootsplash,\nyou can choose\nthem separately"), $logo_thm), Gtk2::VSeparator->new, gtkpack__(new Gtk2::VBox(0, 5), N("Lilo screen"), $combo{lilo}, $lilo_pic, $B_create), Gtk2::VSeparator->new, gtkpack__(new Gtk2::VBox(0, 5), N("Bootsplash"), $combo{boot}, $boot_pic, $thm_button)) ), ), 0, gtkadd(new Gtk2::Frame(N("System mode")), gtkpack__(new Gtk2::VBox(0, 5), gtksignal_connect(gtkset_active(new Gtk2::CheckButton(N("Launch the graphical environment when your system starts")), $x_mode), clicked => sub { $x_box->set_sensitive(!$x_mode); $x_mode = !$x_mode; }), gtkpack__(gtkset_sensitive($x_box = Gtk2::VBox->new(0, 0), $x_mode), gtkpack__(Gtk2::VBox->new(0, 0), my @auto_buttons = gtkradio((N("Yes, I want autologin with this (user, desktop)")) x 2, N("No, I don't want autologin")), ), gtkpack__( my $auto_box = Gtk2::HBox->new, gtkpack( Gtk2::VBox->new, Gtk2::Label->new(N("Default user")), Gtk2::Label->new(N("Default desktop")), ), gtkpack( Gtk2::VBox->new, $user_combo, $desktop_combo ), ) ) ) ), 1, Gtk2::VBox->new, 0, gtkadd(Gtk2::HButtonBox->new, gtksignal_connect(Gtk2::Button->new(N("Cancel")), clicked => sub { ugtk2->exit(0) }), gtksignal_connect(Gtk2::Button->new(N("Ok")), clicked => sub { Xconfig::various::runlevel($x_mode ? 5 : 3); updateAutologin(); ugtk2->exit(0); }), ) ) ); $auto_buttons[0]->signal_connect('toggled' => sub { $auto_box->set_sensitive($auto_buttons[0]->get_active) }); $auto_buttons[1]->signal_connect('toggled' => sub { $auto_box->set_sensitive(!$auto_buttons[1]->get_active) }); $auto_buttons[0]->set_active(1) if $auto_mode->{autologin}; $auto_buttons[1]->set_active(1) if !$auto_mode->{autologin}; $x_box->set_sensitive($x_mode); $auto_box->set_sensitive($auto_mode->{autologin} ? 1 : 0); $window->show_all; #$no_bootsplash and $thm_frame->set_sensitive(0); $thm_frame->hide if !$splash_working; gtkflush(); $w->main; $in->exit(0); sub lilo_choice() { my $bootloader = bootloader::read(); my ($all_hds) = fsedit::get_hds(); my $fstab = [ fsedit::get_all_fstab($all_hds) ]; fs::merge_info_from_fstab($fstab, '', 0, undef); ask: eval { any::setupBootloader($in, $bootloader, $all_hds, $fstab, $ENV{SECURE_LEVEL}) }; my $loader = arch() =~ /ppc/ ? "Yaboot" : "LILO"; my $err = $@; if ($err) { $in->ask_warn('', [ N("Installation of %s failed. The following error occured:", $loader), $err ]); goto ask; } } #------------------------------------------------------------- # launch autologin functions #------------------------------------------------------------- sub updateAutologin() { my ($usern, $deskt) = ($user_combo->entry->get_text, $desktop_combo->entry->get_text); if ($auto_buttons[0]->get_active) { any::set_autologin($usern, $deskt); } else { any::set_autologin(); } }