package install_gtk; # $Id$ use diagnostics; use strict; use my_gtk qw(:helpers :wrappers); use common qw(:common :file :functional); use lang; use devices; #-##################################################################################### #-INTERN CONSTANT #-##################################################################################### my @themes_vga16 = qw(blue blackwhite savane); my @themes_desktop = qw(mdk-Desktop DarkMarble marble3d blueHeart); my @themes_firewall = qw(mdk-Firewall); my @themes = qw(mdk DarkMarble marble3d blueHeart); my (@background1, @background2); #------------------------------------------------------------------------------ sub load_rc { my ($name) = @_; if (my ($f) = grep { -r $_ } map { "$_/$name.rc" } ("share", $ENV{SHARE_PATH}, dirname(__FILE__))) { Gtk::Rc->parse($f); foreach (cat_($f)) { if (/style\s+"background"/ .. /^\s*$/) { @background1 = map { $_ * 256 * 257 } split ',', $1 if /NORMAL.*\{(.*)\}/; @background2 = map { $_ * 256 * 257 } split ',', $1 if /PRELIGHT.*\{(.*)\}/; } } } } sub default_theme { my ($o) = @_; @themes = @themes_desktop if $o->{meta_class} eq 'desktop'; @themes = @themes_firewall if $o->{meta_class} eq 'firewall'; @themes = @themes_vga16 if $o->{simple_themes} || $o->{vga16}; install_theme($o, $o->{theme} || $themes[0]); } #------------------------------------------------------------------------------ sub install_theme { my ($o, $theme) = @_; $o->{theme} = $theme || $o->{theme}; load_rc($_) foreach "themes-$o->{theme}", "install", "themes"; if (my ($font, $font2) = lang::get_x_fontset($o->{lang}, $::rootwidth < 800 ? 10 : 12)) { $font2 ||= $font; Gtk::Rc->parse_string(qq( style "default-font" { fontset = "$font" } style "small-font" { fontset = "$font2" } widget "*" style "default-font" widget "*Steps*" style "small-font" )); } gtkset_background(@background1) unless $::live; #- || testing; create_logo_window($o); create_help_window($o); } #------------------------------------------------------------------------------ sub create_big_help { my ($o) = @_; my $w = my_gtk->new('', grab => 1, force_position => [ $::stepswidth, $::logoheight ]); $w->{rwindow}->set_usize($::logowidth, $::rootheight - $::logoheight); gtkadd($w->{window}, gtkpack_(new Gtk::VBox(0,0), 1, createScrolledWindow(gtktext_insert(new Gtk::Text, $o->{current_help})), 0, gtksignal_connect(my $ok = new Gtk::Button(_("Ok")), "clicked" => sub { Gtk->main_quit }), )); $ok->grab_focus; $w->main; gtkset_mousecursor_normal(); } #------------------------------------------------------------------------------ sub create_help_window { my ($o) = @_; my $w; if ($w = $o->{help_window}) { $_->destroy foreach $w->{window}->children; } else { $w = bless {}, 'my_gtk'; $w->{rwindow} = $w->{window} = new Gtk::Window; $w->{rwindow}->set_uposition($::rootwidth - $::helpwidth, $::rootheight - $::helpheight); $w->{rwindow}->set_usize($::helpwidth, $::helpheight); $w->sync; } my $pixmap = gtkxpm($w->{window}, "$ENV{SHARE_PATH}/help.xpm"); gtkadd($w->{window}, gtkpack_(new Gtk::HBox(0,-2), 0, gtkadd(gtksignal_connect(new Gtk::Button, clicked => sub { create_big_help($o) }), $pixmap), 1, createScrolledWindow($o->{help_window_text} = new Gtk::Text), )); $o->set_help($o->{step}) if $o->{step}; $w->show; $o->{help_window} = $w; } #------------------------------------------------------------------------------ sub create_steps_window { my ($o) = @_; my $PIX_H = my $PIX_W = 21; $o->{steps_window}->destroy if $o->{steps_window}; my $w = bless {}, 'my_gtk'; $w->{rwindow} = $w->{window} = new Gtk::Window; $w->{rwindow}->set_uposition(0, 0); $w->{rwindow}->set_usize($::stepswidth, $::stepsheight); $w->{rwindow}->set_name('Steps'); $w->{rwindow}->set_events('button_press_mask'); #$w->show; gtkadd($w->{window}, gtkpack_(new Gtk::VBox(0,0), (map {; 1, $_ } map { my $step_name = $_; my $step = $o->{steps}{$_}; my $darea = new Gtk::DrawingArea; my $in_button; my $draw_pix = sub { my $pixmap = Gtk::Gdk::Pixmap->create_from_xpm($darea->window, $darea->style->bg('normal'), $_[0]) or die; $darea->window->draw_pixmap ($darea->style->bg_gc('normal'), $pixmap, 0, 0, ($darea->allocation->[2]-$PIX_W)/2 + ($o->{meta_class} eq 'firewall' ? 3 : 0), ($darea->allocation->[3]-$PIX_H)/2, $PIX_W , $PIX_H ); }; my $f = sub { my ($type) = @_; my $color = $step->{done} ? 'green' : $step->{entered} ? 'orange' : 'red'; "$ENV{SHARE_PATH}/step-$color$type.xpm"; }; $darea->set_usize($PIX_W+($o->{meta_class} eq 'firewall' ? 3 : 0),$PIX_H); $darea->set_events(['exposure_mask', 'enter_notify_mask', 'leave_notify_mask', 'button_press_mask', 'button_release_mask' ]); $darea->signal_connect(expose_event => sub { $draw_pix->($f->('')) }); if ($step->{reachable}) { $darea->signal_connect(enter_notify_event => sub { $in_button=1; $draw_pix->($f->('-on')); }); $darea->signal_connect(leave_notify_event => sub { undef $in_button; $draw_pix->($f->('')); }); $darea->signal_connect(button_press_event => sub { $draw_pix->($f->('-click')); }); $darea->signal_connect(button_release_event => sub { $in_button && die "setstep $step_name\n" }); } gtkpack_(new Gtk::HBox(0,5), 0, $darea, 0, new Gtk::Label(translate($step->{text}))); } grep { !eval $o->{steps}{$_}{hidden}; } @{$o->{orderedSteps}}), 0, gtkpack(new Gtk::HBox(0,0), map { my $t = $_; my $w = new Gtk::Button(''); $w->set_name($t); $w->set_usize(0, 7); gtksignal_connect($w, clicked => sub { $::setstep or return; #- just as setstep s install_theme($o, $t); die "theme_changed\n" }); } @themes))); $w->show; $o->{steps_window} = $w; } #------------------------------------------------------------------------------ sub create_logo_window { my ($o) = @_; gtkdestroy($o->{logo_window}); my $w = bless {}, 'my_gtk'; $w->{rwindow} = $w->{window} = new Gtk::Window; $w->{rwindow}->set_uposition($::stepswidth, 0); $w->{rwindow}->set_usize($::logowidth, $::logoheight); $w->{rwindow}->set_name("logo"); $w->show; my $file = $o->{meta_class} eq 'desktop' ? "logo-mandrake-Desktop.xpm" : "logo-mandrake.xpm"; $o->{meta_class} eq 'firewall' and $file = "logo-mandrake-Firewall.xpm"; -r $file or $file = "$ENV{SHARE_PATH}/$file"; -r $file and gtkadd($w->{window}, gtkxpm($w->{window}, $file)); $o->{logo_window} = $w; } #------------------------------------------------------------------------------ sub init_sizes() { ($::rootheight, $::rootwidth) = my_gtk::gtkroot()->get_size; $::live and $::rootheight -= 80; #- ($::rootheight, $::rootwidth) = (min(768, $::rootheight), min(1024, $::rootwidth)); ($::stepswidth, $::stepsheight) = (145, $::rootheight); ($::logowidth, $::logoheight) = ($::rootwidth - $::stepswidth, 40); ($::helpwidth, $::helpheight) = ($::rootwidth - $::stepswidth, 104); ($::windowwidth, $::windowheight) = ($::rootwidth - $::stepswidth, $::rootheight - $::helpheight - $::logoheight); } #------------------------------------------------------------------------------ sub createXconf { my ($file, $mouse_type, $mouse_dev, $wacom_dev) = @_; devices::make("/dev/kbd") if arch() =~ /^sparc/; #- used by Xsun style server. symlinkf($mouse_dev, "/dev/mouse"); #- needed for imlib to start on 8-bit depth visual. symlink("/tmp/stage2/etc/imrc", "/etc/imrc"); symlink("/tmp/stage2/etc/im_palette.pal", "etc/im_palette.pal"); my $wacom; if ($wacom_dev) { $wacom_dev = devices::make($wacom_dev); $wacom = <$file" or die "can't create X configuration file $file"; print F <new; my ($width, $height, $offset) = (210, round_up($::windowheight - 150, 6), 25); my ($bw, $bh) = ($width / 3, $height / 3); gtkadd($w->{window}, gtkpack(new Gtk::VBox(0,0), my $darea = gtkset_usize(new Gtk::DrawingArea, $width+1, $height+1), '', create_okcancel($w, '', '', "edge"), ), ); my $draw_rect; $draw_rect = sub { my ($black, $fill, $rect) = @_; $draw_rect->(0, 1, $rect) if !$fill; #- blank it first $darea->window->draw_rectangle($black ? $darea->style->fg_gc('normal') : $darea->style->bg_gc('normal'), $fill, @$rect); $darea->draw($rect); }; my $paintWheel = sub { my ($x, $y, $w, $h) = ($width / 2 - $bw / 6, $bh / 4, $bw / 3, $bh / 2); $mouse->{nbuttons} = max($mouse->{nbuttons}, 5); #- it means, the mouse has more than 3 buttons... $draw_rect->(1, 0, [ $x, $y, $w, $h ]); my $offset = 0 if 0; $offset += $_[0] if $_[0]; my $step = 10; for (my $i = $offset % $step; $i < $h; $i += $step) { $draw_rect->(1, 1, [ $x, $y + $i, $w, min(2, $h - $i) ]); } }; my $paintButton = sub { my ($nb, $pressed) = @_; my $rect = [ $bw * $nb, 0, $bw, $bh ]; $draw_rect->(1, $pressed, $rect); $paintWheel->(0) if $nb == 1 && $mouse->{nbuttons} > 3; }; my $draw_text = sub { my ($t, $y) = @_; my $font = $darea->style->font; my $w = $font->string_width($t); $darea->window->draw_string($font, $darea->style->fg_gc('normal'), ($width - $w) / 2, $y, $t); }; my $default_time = 10; my $time = $default_time; $darea->signal_connect(button_press_event => sub { my $b = $_[1]{button}; $time = $default_time; $b >= 4 ? $paintWheel->($b == 4 ? -1 : 1) : $paintButton->($b - 1, 1); }); $darea->signal_connect(button_release_event => sub { my $b = $_[1]{button}; $paintButton->($b - 1, 0) if $b < 4; }); $darea->size($width, $height); $darea->set_events([ 'button_press_mask', 'button_release_mask' ]); $w->sync; # HACK $draw_rect->(1, 0, [ 0, 0, $width, $height]); $draw_text->(_("Please test the mouse"), 2 * $bh - 20); $draw_text->(_("To activate the mouse,"), 2 * $bh + 10) if $mouse->{XMOUSETYPE} eq 'IMPS/2'; $draw_text->(_("MOVE YOUR WHEEL!"), 2 * $bh + 30) if $mouse->{XMOUSETYPE} eq 'IMPS/2'; $paintButton->($_, 0) foreach 0..2; $w->{cancel}->grab_focus; # my $timeout = Gtk->timeout_add(1000, sub { if ($time-- == 0) { log::l("timeout test_mouse"); undef $w->{retval}; Gtk->main_quit } 1 }); # my $b = before_leaving { log::l("removing timeout"); Gtk->timeout_remove($timeout) }; $w->main; } 1; se common; use modules; use fs; use fsedit; use run_program; use partition_table qw(:types); use log; use lang; use detect_devices; sub symlinkf_short { my ($dest, $file) = @_; if (my $l = readlink $dest) { $dest = $l if $l =~ m!^/!; } -d $file and log::l("$file already exists and is a directory! writing in directory may be needed, not overwriting"), return; symlinkf($dest, $file); } #- run very soon at stage2 start, setup things on tmpfs rw / that #- were not necessary to start stage2 itself (there were setup #- by stage1 of course) sub init { my ($o) = @_; check_for_xserver() and c::bind_textdomain_codeset('libDrakX2', 'UTF8'); -d '/lib/modules/' . c::kernel_version() or warn("ERROR: kernel package " . c::kernel_version() . " not installed\n"), c::_exit(1); modules::load_category('bus/usb'); *c::pcmcia_probe = \&detect_devices::pcmcia_probe; $o->{pcmcia} ||= !$::noauto && c::pcmcia_probe(); install_steps::setupSCSI($o); drakx_stuff: $o->{steps}{$_} = { reachable => 1, text => $_ } foreach qw(autoSelectLanguage configMove selectMouse setRootPassword addUser configureNetwork miscellaneous selectMouse); $o->{orderedSteps_orig} = $o->{orderedSteps}; $o->{orderedSteps} = [ qw(selectLanguage acceptLicense selectMouse setupSCSI miscellaneous selectKeyboard setRootPassword addUser configureNetwork configMove ) ]; $o->{steps}{first} = $o->{orderedSteps}[0]; } sub enable_service { run_program::run('/sbin/chkconfig', '--level', 5, $_[0], 'on'); } sub disable_service { run_program::run('/sbin/chkconfig', '--del', $_[0], 'on'); } sub install2::configMove { my $o = $::o; security::level::set($o->{security}); require install_steps; install_steps::addUser($o); # for test, when replaying wizard on an already configured machine while ($#{$o->{users}} eq -1) { install_steps::addUser($o); } $::noauto and goto after_autoconf; my $_wait = $o->wait_message(N("Auto configuration"), N("Please wait, detecting and configuring devices...")); #- automatic printer, timezone, network configs require install_steps_interactive; if (cat_('/proc/mounts') !~ /nfs/) { install_steps_interactive::configureNetwork($o); enable_service('network'); } enable_service('netfs'); install_steps_interactive::summaryBefore($o); modules::load_category('multimedia/sound'); enable_service('sound'); detect_devices::isLaptop() or enable_service('numlock'); after_autoconf: require timezone; timezone::write($o->{timezone}); $o->{useSupermount} = 1; fs::set_removable_mntpoints($o->{all_hds}); require fs::mount_options; fs::mount_options::set_all_default($o->{all_hds}, %$o, lang::fs_options($o->{locale})); $o->{modules_conf}->write; require mouse; mouse::write_conf($o, $o->{mouse}, 1); #- write xfree mouse conf detect_devices::install_addons(''); foreach my $step (@{$o->{orderedSteps_orig}}) { next if member($step, @{$o->{orderedSteps}}); while (my $f = shift @{$o->{steps}{$step}{toBeDone} || []}) { log::l("doing remaining toBeDone for undone step $step"); eval { &$f() }; $o->ask_warn(N("Error"), [ N("An error occurred, but I don't know how to handle it nicely. Continue at your own risk."). formatError($@) || $@ ]) if $@; } } run_program::run('killall', 'Xorg'); output_p("$::prefix/etc/rpm/macros", "%_install_langs all\n"); # workaround init reading inittab before any.pm alters it: if ($::o->{autologin}) { run_program::run('chkconfig', 'dm', 'on'); run_program::run('telinit', 'Q'); } # prevent dm service to fail to startup because of /tmp/.font-unix's permissions: run_program::run('service', 'xfs', 'stop'); c::_exit(0); } sub automatic_xconf { my ($o) = @_; log::l('automatic XFree configuration'); any::devfssymlinkf($o->{mouse}, 'mouse'); local $o->{mouse}{device} = 'mouse'; require Xconfig::default; require class_discard; $o->{raw_X} = Xconfig::default::configure(class_discard->new, { KEYBOARD => 'uk' }, $o->{mouse}); #- using uk instead of us for now to have less warnings require Xconfig::main; Xconfig::main::configure_everything_auto_install($o->{raw_X}, class_discard->new, {}, { allowNVIDIA_rpms => sub { [] }, allowATI_rpms => sub { [] }, allowFB => $o->{allowFB} }); modules::load_category('various/agpgart'); my $file = '/etc/X11/XF86Config'; $file = "$file-4" if -e "$file-4"; my ($Driver) = cat_($file) =~ /Section "Device".*Driver\s*"(.*?)"/s; if ($Driver eq 'nvidia') { modules::load('nvidia'); } my $lib = 'libGL.so.1'; symlinkf_short(-e "/usr/lib/$lib.$Driver" ? "/usr/lib/$lib.$Driver" : "/usr/X11R6/lib/$lib", "/etc/X11/$lib"); } sub handleI18NClp {} 1;