#!/usr/bin/perl use strict; use diagnostics; use lib qw(/usr/lib/libDrakX); use standalone; use common; require harddrake::data; use ugtk2 qw(:create :helpers :wrappers); use interactive; # { field => [ short_translation, full_description] } my %fields = ( "alternative_drivers" => [ N("Alternative drivers"), N("the list of alternative drivers for this sound card") ], "bus" => [ N("Bus"), N("this is the physical bus on which the device is plugged (eg: PCI, USB, ...)") ], "channel" => [ N("Channel"), N("EIDE/SCSI channel") ], "bogomips" => [ N("Bogomips"), N("The GNU/Linux kernel needs to run a calculation loop at boot time to initialize a timer counter. Its result is stored as bogomips as a way to \"benchmark\" the cpu.") ], "bus_id" => [ N("Bus identification"), N("- PCI and USB devices: this lists the vendor, device, subvendor and subdevice PCI/USB ids") ], "bus_location" => [ N("Location on the bus"), N("- pci devices: this gives the PCI slot, device and function of this card - eide devices: the device is either a slave or a master device - scsi devices: the scsi bus and the scsi device ids") ], "cache size" => [ N("Cache size"), N("Size of the (second level) cpu cache") ], "coma_bug" => [ N("Coma bug"), N("Whether this cpu has the Cyrix 6x86 Coma bug") ], "cpu family" => [ N("Cpuid family"), N("Family of the cpu (eg: 6 for i686 class)") ], "cpuid level" => [ N("Cpuid level"), N("Information level that can be obtained through the cpuid instruction") ], "cpu MHz" => [ N("Frequency (MHz)"), N("The cpu frequency in Mhz (Mega herz which in first approximation may be coarsely assimilated to number of instructions the cpu is able to execute per second)") ], "description" => [ N("Description"), N("This field describes the device") ], "device" => [ N("Old device file"), N("old static device name used in dev package") ], "devfs_device" => [ N("New devfs device"), N("new dynamic device name generated by core kernel devfs") ], "driver" => [ N("Module"), N("the module of the GNU/Linux kernel that handles the device") ], "flags" => [ N("Flags"), N("CPU flags reported by the kernel") ], "fdiv_bug" => [ N("Fdiv bug"), N("Early Intel Pentium chips manufactured have a bug in their floating point processor which did not achieve the required precision when performing a Floating point DIVision (FDIV)") ], "fpu" => [ N("Is FPU present"), N("yes means the processor has an arithmetic coprocessor") ], "fpu_exception" => [ N("Whether the FPU has an irq vector"), N("yes means the arithmetic coprocessor has an exception vector attached") ], "f00f_bug" => [N("F00f bug"), N("Early pentiums were buggy and freezed when decoding the F00F bytecode")], "hlt_bug" => [ N("Halt bug"), N("Some of the early i486DX-100 chips cannot reliably return to operating mode after the \"halt\" instruction is used") ], "info" => [N("Floppy format"), N("Format of floppies the drive accept")], "level" => [N("Level"), N("Sub generation of the cpu")], "media_type" => [ N("Media class"), N("class of hardware device") ], "Model" => [N("Model"), N("hard disk model")], "model" => [N("Model"), N("Generation of the cpu (eg: 8 for PentiumIII, ...)")], "model name" => [N("Model name"), N("Official vendor name of the cpu")], "nbuttons" => [ N("Number of buttons"), "the number of buttons the mouse have" ], "name" => [ N("Name"), "the name of the cpu" ], "port" => [N("Port"), N("network printer port")], "processor" => [ N("Processor ID"), N("the number of the processor") ], "stepping" => [ N("Model stepping"), N("Stepping of the cpu (sub model (generation) number)") ], "type" => [ N("Type"), N("The type of bus on which the mouse is connected") ], "Vendor" => [ N("Vendor"), N("the vendor name of the device") ], "vendor_id" => [ N("Vendor"), N("the vendor name of the processor") ] ); my ($in, %IDs, $pid, $w); my (%options, %check_boxes); my $conffile = "/etc/sysconfig/harddrake2/ui.conf"; my ($modem_check_box, $printer_check_box, $current_device, $current_configurator); my @menu_items = ( { path => N("/_File"), type => '' }, { path => N("/_File").N("/_Quit"), accelerator => N("Q"), callback => \&quit_global }, { path => N("/_Options").N("/Autodetect _printers"), type => '', callback => sub { $options{PRINTERS_DETECTION} = $check_boxes{PRINTERS_DETECTION}->active } }, { path => N("/_Options").N("/Autodetect _modems"), type => '', callback => sub { $options{MODEMS_DETECTION} = $check_boxes{MODEMS_DETECTION}->active } }, { path => N("/_Options").N("/Autodetect _jazz drives"), type => '', callback => sub { $options{JAZZ_DETECTION} = $check_boxes{JAZZ_DETECTION}->active } }, { path => N("/_Help"), type => '' }, { path => N("/_Help").N("/_Help"), callback => sub { unless (fork()) { exec("drakhelp Drakxtools-Guide.html/harddrake.html") } } }, { path => N("/_Help").N("/_Fields description"), callback => sub { if ($current_device) { $in->ask_warn(N("Harddrake help"), N("Description of the fields:\n\n") . join("\n\n", map { if_($fields{$_}[0], "$fields{$_}[0]: $fields{$_}[1]") } sort keys %$current_device)) } else { $in->ask_warn(N("Select a device !"), N("Once you've selected a device, you'll be able to see the device information in fields displayed on the right frame (\"Information\")")) } } }, { path => N("/_Help").N("/_Report Bug"), callback => sub { unless (fork()) { exec("drakbug --report harddrake2 &") } } }, { path => N("/_Help").N("/_About..."), callback => sub { $in->ask_warn(N("About Harddrake"), join("", N("This is HardDrake, a Mandrake hardware configuration tool.\nVersion:"), " $harddrake::data::version\n", N("Author:"), " Thierry Vignaud \n\n", formatAlaTeX($::license))); } } ); my ($sig_id, $wait); $in = 'interactive'->vnew('su', 'default'); { local $::isEmbedded = 0; # to prevent sub window embedding $wait = $in->wait_message(N("Please wait"), N("Detection in progress")); gtkflush(); } %options = getVarsFromSh($conffile); # Build the gui add_icon_path('/usr/share/pixmaps/harddrake2/'); $w = ugtk2->new(N("Harddrake2 version ") . $harddrake::data::version); $::main_window = $w->{rwindow} unless $::isEmbedded; my ($menubar, $factory); unless ($::isEmbedded) { $w->{window}->set_size_request(805, 550); ($menubar, $factory) = create_factory_menu($w->{rwindow}, @menu_items); } my $tree_model = Gtk2::TreeStore->new(Gtk2::GType->OBJECT, Gtk2::GType->STRING); my $statusbar; $w->{window}->add(gtkpack_(0, Gtk2::VBox->new(0, 0), if_(!$::isEmbedded, 0, $menubar), 1, create_hpaned(gtkadd(new Gtk2::Frame(N("Detected hardware")), create_scrolled_window(gtkset_size_request(my $tree = Gtk2::TreeView->new_with_model($tree_model), 350, -1))), gtkpack_(0, Gtk2::VBox->new(0, 0), 1, gtkadd(gtkset_size_request(new Gtk2::Frame(N("Information")), 300, 450), create_scrolled_window(my $text = Gtk2::TextView->new)), 0, my $module_cfg_button = gtksignal_connect(new Gtk2::Button(N("Configure module")), clicked => sub { require modules::interactive; modules::interactive::config_window($in, $current_device); gtkset_mousecursor_normal(); }), 0, my $config_button = gtksignal_connect(new Gtk2::Button(N("Run config tool")), # we've a configurator, let's add a button for it and show it clicked => sub { return 1 if defined $pid; if ($pid = fork()) { $sig_id = $statusbar->push($statusbar->get_context_id("id"), N("Running \"%s\" ...", $current_configurator)); } else { exec($current_configurator) or die "$current_configurator missing\n"; } }) ), 'resize2' => 1, 'resize1' => 1, 'shrink1' => 0, 'shrink2' => 1 ), 0, $statusbar = new Gtk2::Statusbar, if_($::isEmbedded, 0, gtksignal_connect(my $but = new Gtk2::Button(N("Quit")), 'clicked' => \&quit_global)) ) ); # $tree->set_column_auto_resize(0, 1); my (%data, %configurators); $tree->append_column(my $pixcolumn = Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererPixbuf->new, 'pixbuf' => 0)); $tree->append_column(my $textcolumn = Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 1)); $tree->set_headers_visible(0); my $selection = gtksignal_connect($tree->get_selection(), 'changed' => sub { my ($select) = @_; my ($model, $iter) = $select->get_selected(); if ($model) { my $id = $model->get($iter, 1); $iter->free; $current_device = $data{$id}; if ($current_device) { gtktext_insert($text, [ map { # The U+200E character is to force LTR display, as what # what follows the colon is always in LTR (device names, # paths, etc), this ensures proper displaying of names # like /dev/fd0 (otherwise it gets 'dev/fd0/'). # it must come *after* the space, as the space must follow # the colon following the direction of writting. if_($fields{$_}[0], [ $fields{$_}[0] . ": \x{200e}", { 'foreground' => 'royalblue3', 'weight' => Gtk2::Pango->WEIGHT_BOLD } ], [ "$current_device->{$_}\n\n", { 'foreground' => ($_ eq 'driver' && $current_device->{$_} =~ /^(unknown|Bad:)/ ? 'indian red' : 'black') } ]) } sort keys %$current_device ]); foreach (keys %$current_device) { print "Warning: skip \"$_\" field => \"$current_device->{$_}\"\n\n" unless $fields{$_}[0]; }; # hide buttons if needed # we've valid driver, let's offer to configure it show_hide($current_device->{driver} !~ /(unknown|.*\|.*)/ && $current_device->{driver} !~ /^Card:/, $module_cfg_button); $current_configurator = $configurators{$id}; show_hide(-x first(split /\s+/, $current_configurator), $config_button); # strip arguments for -x test return 1; } } $text->get_buffer->set_text(N_("Click on a device in the left tree in order to display its information here."), -1); $config_button->hide; $module_cfg_button->hide; }); # Fill the graphic devices tree with a "tree branch" widget per device category foreach (@harddrake::data::tree) { my ($Ident, $title, $icon, $configurator, $detector) = @$_; next if ref($detector) ne "CODE"; #skip class witouth detector next if $Ident =~ /(MODEM|PRINTER)/ && $::testing; next if $Ident =~ /JAZZ/ && !$options{JAZZ_DETECTION}; next if $Ident =~ /MODEM/ && !$options{MODEMS_DETECTION}; next if $Ident =~ /PRINTER/ && !$options{PRINTERS_DETECTION}; my @devices = &$detector; next unless @devices; # Skip empty class (no devices) my $parent_iter = $tree_model->append_set(undef, [ 0 => gtkcreate_pixbuf($icon), 1 => $title ]); # Fill the graphic tree with a "tree leaf" widget per device foreach (@devices) { # we really should test for $title there: if ($_->{bus} eq "PCI") { my $i = $_; $_->{bus_id} = join ':', map { if_($i->{$_} ne "65535", sprintf("%lx", $i->{$_})) } qw(vendor id subvendor subid); $_->{bus_location} = join ':', map { sprintf("%lx", $i->{$_}) } qw(pci_bus pci_device pci_function); } # split description into manufacturer/description ($_->{Vendor}, $_->{description}) = split(/\|/, $_->{description}) if $_->{description}; if ($_->{val}) { # Scanner ? my $val = $_->{val}; ($_->{Vendor}, $_->{description}) = split(/\|/, $val->{DESCRIPTION}); } # EIDE detection incoherency: if ($_->{bus} eq 'ide') { $_->{channel} = $_->{channel} ? N("secondary") : N("primary"); delete $_->{info}; } elsif ($_->{bus} !~ /USB|PCI/) { # SCSI detection incoherency: my $i = $_; $_->{bus_location} = join ':', map { sprintf("%lx", $i->{$_}) } qw(bus id); } if ($Ident =~ /FLOPPY|ZIP|DVDROM|CDROM|BURNER/) { $configurator = "/usr/sbin/diskdrake --removable=$_->{device}"; } elsif ($Ident eq "AUDIO") { require harddrake::sound; my $alter = harddrake::sound::get_alternative($_->{driver}); $_->{alternative_drivers} = join(':', @$alter) if $alter->[0] ne 'unknown'; } foreach my $i (qw(vendor id subvendor subid pci_bus pci_device pci_function MOUSETYPE XMOUSETYPE unsafe val devfs_prefix wacom auxmouse)) { delete $_->{$i} }; my $custom_id = harddrake::data::custom_id($_, $title); $custom_id .= ' ' while $data{$custom_id}; # get a unique id for eg bt8xx audio/video funtions $_->{device} = '/dev/'.$_->{device} if $_->{device}; $tree_model->append_set($parent_iter, [ 1 => $custom_id ])->free; $data{$custom_id} = $_; $configurators{$custom_id} = $configurator; } $tree->expand_row($tree_model->get_path($parent_iter), 1) unless $title eq N_("Unknown/Others"); $parent_iter->free; } $SIG{CHLD} = sub { undef $pid; $statusbar->pop($sig_id) }; $w->{rwindow}->signal_connect(delete_event => \&quit_global); $w->{rwindow}->set_position('center') unless $::isEmbedded; foreach (['PRINTERS_DETECTION', N("/Autodetect printers")], ['MODEMS_DETECTION', N("/Autodetect modems")], ['JAZZ_DETECTION', N("/Autodetect jazz drives")],) { $options{$_->[0]} = 0 unless defined($options{$_->[0]}); # force detection by default unless ($::isEmbedded) { $check_boxes{$_->[0]} = $factory->get_widget("
".N("/Options").$_->[1]); $check_boxes{$_->[0]}->set_active($options{$_->[0]}); # restore saved values } } $textcolumn->set_min_width(350); #$textcolumn->set_minmax_width(400); $textcolumn->set_sizing('GTK_TREE_VIEW_COLUMN_AUTOSIZE');#GROW_ONLY #$tree->columns_autosize(); $w->{rwindow}->show_all; undef $wait; gtkset_mousecursor_normal(); $_->hide foreach $module_cfg_button, $config_button; # hide buttons while no device $w->main; sub quit_global { kill(15, $pid) if $pid; setVarsInSh($conffile, \%options); ugtk2->exit(0); } sub show_hide { my ($bool, $button) = @_; if ($bool) { $button->show } else { $button->hide } }