#!/usr/bin/perl # DrakBoot # $Id$ # Copyright (C) 2001-2004 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 = any { /^--splash$/ } @ARGV; my $in = 'interactive'->vnew('su'); if (!$in->isa('interactive::gtk') || any { /^--boot$/ } @ARGV) { $::isWizard = 1; 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 $switch_theme = '/usr/share/bootsplash/scripts/switch-themes'; my $remove_theme = '/usr/share/bootsplash/scripts/remove-theme'; my $w = ugtk2->new($splash_working ? N("Graphical boot theme selection") : N("System mode")); 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 = Gtk2::ComboBox->new_text; $user_combo->set_popdown_strings(list_users()); $user_combo->entry->set_text($auto_mode->{autologin}) if $auto_mode->{autologin}; my $desktop_combo = Gtk2::ComboBox->new_text; $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/', 'sysconfig' => '/etc/sysconfig/bootsplash', '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 $kernel_release = `uname -r`; chomp $kernel_release; my $initrd = "/boot/initrd-$kernel_release.img" if -f "/boot/initrd-$kernel_release.img"; my $cur_res = `/usr/share/bootsplash/scripts/detect-resolution $initrd`; $cur_res =~ m/(\d+x\d+)x\d+/ and $cur_res = $1; #- verify that current resolution is ok if (!$cur_res) { $no_bootsplash = 1; #- we can't select any theme we're not in Framebuffer mode :-/ $cur_res = '800x600' } $no_bootsplash = 0 if $::testing; my $splash_mode = !$no_bootsplash; my $keep_logo = 1; if (-r $themes{sysconfig}) { my $SYSF; open $SYSF, $themes{sysconfig} or die "Can't open $themes{sysconfig}\n"; while (<$SYSF>) { /^SPLASH=no/ and $splash_mode = 0; /^THEME=(.*)/ and -f "$themes{path}$1$themes{boot}{path}bootsplash-$cur_res.jpg" and $themes{default} = $1; /^LOGO_CONSOLE=(.*)/ and $keep_logo = $1 ne 'no'; } close($SYSF); } my @thms; 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{boot}{path}bootsplash-$cur_res.jpg" and push @boot_thms, $_; } } my %combo = ('thms' => '', 'lilo' => '', 'boot' => ''); foreach (keys(%combo)) { $combo{$_} = gtkset_size_request(Gtk2::ComboBox->new_text, 10, -1); } $combo{boot}->set_popdown_strings(@boot_thms); $combo{boot}->entry->set_text($themes{default}); my $boot_pic = gtkcreate_img($themes{def_thmb}); change_image($boot_pic, $themes{default}); my $_thm_button = Gtk2::Button->new(N("Install themes")); my $_B_create = gtksignal_connect(Gtk2::Button->new(N("Create new theme")), clicked => sub { system('/usr/sbin/draksplash ') }); #- ******** action to take on changing combos values $combo{boot}->entry->signal_connect(changed => sub { change_image($boot_pic, $combo{boot}->entry->get_text) }); my ($x_box, $splash_box); my $boot_warn = 1; gtkadd($window, gtkpack_(Gtk2::VBox->new(0,0), ($splash_working ? (1, gtkpack_(gtkset_border_width(Gtk2::VBox->new(0, 5), 5), 0, gtksignal_connect(gtkset_active(Gtk2::CheckButton->new(N("Use graphical boot")), $splash_mode), clicked => sub { $splash_mode = !$splash_mode; if ($boot_warn && $no_bootsplash && $splash_mode) { $in->ask_warn(N("Warning"), [ N("Your system bootloader is not in framebuffer mode. To activate graphical boot, select a graphic video mode from the bootloader configuration tool.") ]); $boot_warn = 0 } $splash_box->set_sensitive($splash_mode); }), 1, gtkpack(gtkset_sensitive($splash_box = Gtk2::HBox->new(0, 0), $splash_mode), gtkpack__(Gtk2::VBox->new(0, 5), N("Theme"), $combo{boot}, #gtksignal_connect(Gtk2::CheckButton->new(N("Display theme\nunder console")), clicked => sub { invbool(\$keep_logo) }), gtksignal_connect(gtkset_active(Gtk2::CheckButton->new(N("Display theme\nunder console")), $keep_logo), clicked => sub { invbool(\$keep_logo) }) ), Gtk2::VSeparator->new, gtkpack__(Gtk2::VBox->new(0, 5), $boot_pic)) ), ) : (1, gtkpack__(Gtk2::VBox->new(0, 5), gtksignal_connect(gtkset_active(Gtk2::CheckButton->new(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("No, I don't want autologin")) x 2, N("Yes, I want autologin with this (user, desktop)")), ), 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 ), ) ) ) ), 0, create_okcancel({ cancel_clicked => sub { ugtk2->exit(0) }, ok_clicked => sub { Xconfig::various::runlevel($x_mode ? 5 : 3); $splash_working or updateAutologin(); $no_bootsplash or update_bootsplash($combo{boot}->entry->get_text, ,$splash_mode, $keep_logo); ugtk2->exit(0); } }, ), ) ) ); if (!$splash_working) { $auto_buttons[1]->signal_connect('toggled' => sub { $auto_box->set_sensitive($auto_buttons[1]->get_active) }); $auto_buttons[0]->signal_connect('toggled' => sub { $auto_box->set_sensitive(!$auto_buttons[0]->get_active) }); $auto_buttons[1]->set_active(1) if $auto_mode->{autologin}; $auto_buttons[0]->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; gtkflush(); $w->main; $in->exit(0); sub lilo_choice() { my $bootloader = bootloader::read(); my $all_hds = fsedit::get_hds(); fs::get_raw_hds('', $all_hds); fs::get_info_from_fstab($all_hds, ''); my $fstab = [ fsedit::get_all_fstab($all_hds) ]; ask: eval { my $before = fs::fstab_to_string($all_hds); any::setupBootloader($in, $bootloader, $all_hds, $fstab, $ENV{SECURE_LEVEL}); if ($before ne fs::fstab_to_string($all_hds)) { #- for /tmp using tmpfs when "clean /tmp" is chosen fs::write_fstab($all_hds); } }; my $err = $@; if ($err && $err !~ /wizcancel/) { # BUG: note that the following message won't speak about the right bootloader if user is currently switching between # various bootloaders and if the error occured before boot sector get overwritten by bootloader installer $in->ask_warn(N("Error"), [ N("Installation of %s failed. The following error occured:", bootloader::detect_bootloader()), $err ]); goto ask; } } #------------------------------------------------------------- # launch autologin functions #------------------------------------------------------------- sub updateAutologin() { my ($usern, $deskt) = ($user_combo->entry->get_text, $desktop_combo->entry->get_text); $::testing and return; if ($auto_buttons[1]->get_active) { any::set_autologin($usern, $deskt); } else { any::set_autologin(); } } sub update_bootsplash { my ($theme, $splash_mode, $keep_logo) = @_; #- theme scripts will update SPLASH value in sysconfig file if (-x $switch_theme) { my $logo_console = $keep_logo ? 'theme' : 'no'; if ($::testing) { if ($splash_mode) { print "substInFile { s/^LOGO_CONSOLE=.*/LOGO_CONSOLE=$logo_console/ } $themes{sysconfig}\n"; print "system($switch_theme, $theme)\n"; } else { print "system($remove_theme, $theme)\n"; } } else { if ($splash_mode) { substInFile { s/^LOGO_CONSOLE=.*/LOGO_CONSOLE=$logo_console/ } $themes{sysconfig}; system($switch_theme, $theme); } else { system($remove_theme, $theme); } } } } sub change_image { my ($boot_pic, $val) = @_; my $img_file = $themes{path} . $val . $themes{boot}{path}."bootsplash-$cur_res.jpg"; -f $img_file or return; my $boot_pixbuf = gtkcreate_pixbuf($img_file); $boot_pixbuf = $boot_pixbuf->scale_simple(300, 200, 'nearest'); $boot_pic->set_from_pixbuf($boot_pixbuf); }