diff options
Diffstat (limited to 'perl-install/Xconfig/monitor.pm')
-rw-r--r-- | perl-install/Xconfig/monitor.pm | 138 |
1 files changed, 91 insertions, 47 deletions
diff --git a/perl-install/Xconfig/monitor.pm b/perl-install/Xconfig/monitor.pm index 008e0aef8..07e228e34 100644 --- a/perl-install/Xconfig/monitor.pm +++ b/perl-install/Xconfig/monitor.pm @@ -30,63 +30,61 @@ my @HorizSync_ranges = ( "31.5-94.0", ); -sub configure { - my ($in, $raw_X, $nb_monitors, $o_ddc_info, $b_auto) = @_; - my $monitors = [ $raw_X->get_or_new_monitors($nb_monitors) ]; - if ($o_ddc_info) { - put_in_hash($monitors->[0], $o_ddc_info); - } - my $head_nb = 1; - foreach my $monitor (@$monitors) { - choose($in, $monitor, @$monitors > 1 ? $head_nb++ : 0, $b_auto) or return; +sub from_raw_X { + my ($raw_X) = @_; + + my $monitor = $raw_X->get_monitor; + if (!$monitor->{HorizSync}) { + put_in_hash($monitor, getinfoFromDDC()); } - $raw_X->set_monitors(@$monitors); - $monitors; + $monitor; +} + +sub configure { + my ($in, $raw_X, $b_auto) = @_; + + my $monitor = from_raw_X($raw_X); + choose($in, $monitor, $b_auto) or return; + $raw_X->set_monitors($monitor); + $monitor; } sub configure_auto_install { my ($raw_X, $old_X) = @_; - if ($old_X->{monitor}) { - #- keep compatibility - $old_X->{monitor}{VertRefresh} = $old_X->{monitor}{vsyncrange}; - $old_X->{monitor}{HorizSync} = $old_X->{monitor}{hsyncrange}; - - #- new name - $old_X->{monitors} = [ delete $old_X->{monitor} ]; + my $old_monitor = $old_X->{monitor} || {}; + my %rename = (vsyncrange => 'VertRefresh', hsyncrange => 'HorizSync'); + foreach (keys %rename) { + my $v = $old_monitor->{$_} or next; + $old_monitor->{$rename{$_}} = $v; } - my $monitors = [ $raw_X->get_or_new_monitors($old_X->{monitors} ? @{$old_X->{monitors}} : 1) ]; - mapn { - my ($monitor, $auto_install_monitor) = @_; - put_in_hash($monitor, $auto_install_monitor); - } $monitors, $old_X->{monitors} if $old_X->{monitors}; + my $monitor = from_raw_X($raw_X); + put_in_hash($monitor, $old_monitor); - if (!$monitors->[0]{HorizSync}) { - put_in_hash($monitors->[0], getinfoFromDDC()); + my $monitors = monitors(); + if (!configure_automatic($monitor, $monitors)) { + good_default_monitor() =~ /(.*)\|(.*)/ or internal_error("bad good_default_monitor"); + put_in_hash($monitor, { VendorName => $1, ModelName => $2 }); + configure_automatic($monitor, $monitors) or internal_error("good_default_monitor (" . good_default_monitor() . ") is unknown in MonitorDB"); } - - my $monitors_db = monitors_db(); - foreach my $monitor (@$monitors) { - configure_automatic($monitor, $monitors_db) or put_in_hash($monitor, { HorizSync => '31.5-35.1', VertRefresh => '50-61' }); - } - $raw_X->set_monitors(@$monitors); - $monitors; + $raw_X->set_monitors($monitor); + $monitor; } sub choose { - my ($in, $monitor, $head_nb, $b_auto) = @_; + my ($in, $monitor, $b_auto) = @_; - my $monitors_db = monitors_db(); + my $monitors = monitors(); - my $ok = configure_automatic($monitor, $monitors_db); + my $ok = configure_automatic($monitor, $monitors); if ($b_auto) { log::l("Xconfig::monitor: auto failed") if !$ok; return $ok; } - my %h_monitors = map {; "$_->{VendorName}|$_->{ModelName}" => $_ } @$monitors_db; + my %h_monitors = map {; "$_->{VendorName}|$_->{ModelName}" => $_ } @$monitors; ask_monitor: my $merged_name = do { @@ -104,7 +102,7 @@ sub choose { }; $in->ask_from_({ title => N("Monitor"), - messages => $head_nb ? N("Choose a monitor for head #%d", $head_nb) : N("Choose a monitor"), + messages => N("Choose a monitor"), interactive_help_id => 'configureX_monitor' }, [ { val => \$merged_name, separator => '|', @@ -118,8 +116,8 @@ sub choose { if ($merged_name eq "Plug'n Play") { local $::noauto = 0; #- hey, you asked for plug'n play, so i do probe! delete @$monitor{'VendorName', 'ModelName', 'EISA_ID'}; - put_in_hash($monitor, getinfoFromDDC()) if $head_nb <= 1; - if ($head_nb > 1 || configure_automatic($monitor, $monitors_db)) { + put_in_hash($monitor, getinfoFromDDC()); + if (configure_automatic($monitor, $monitors)) { $monitor->{VendorName} = "Plug'n Play"; } else { $in->ask_warn('', N("Plug'n Play probing failed. Please select the correct monitor")); @@ -145,11 +143,11 @@ that is beyond the capabilities of your monitor: you may damage your monitor. } sub configure_automatic { - my ($monitor, $monitors_db) = @_; + my ($monitor, $monitors) = @_; if ($monitor->{EISA_ID}) { log::l("EISA_ID: $monitor->{EISA_ID}"); - if (my $mon = find { lc($_->{EISA_ID}) eq $monitor->{EISA_ID} } @$monitors_db) { + if (my $mon = find { lc($_->{EISA_ID}) eq $monitor->{EISA_ID} } @$monitors) { add2hash($monitor, $mon); log::l("EISA_ID corresponds to: $monitor->{ModelName}"); } elsif (!$monitor->{HorizSync} || !$monitor->{VertRefresh}) { @@ -157,7 +155,7 @@ sub configure_automatic { delete @$monitor{'VendorName', 'ModelName', 'EISA_ID'}; } } else { - if (my $mon = find { $_->{VendorName} eq $monitor->{VendorName} && $_->{ModelName} eq $monitor->{ModelName} } @$monitors_db) { + if (my $mon = find { $_->{VendorName} eq $monitor->{VendorName} && $_->{ModelName} eq $monitor->{ModelName} } @$monitors) { put_in_hash($monitor, $mon); } } @@ -165,8 +163,51 @@ sub configure_automatic { return $monitor->{HorizSync} && $monitor->{VertRefresh}; } +# Parse XFree86 log in case with got not valuable information from +# ddcxinfos. NOTE: this is only safe at install stage. +sub getinfoFromXFree() { + my $xf86log = "/var/log/XFree86.0.log"; + $::isInstall && -r $xf86log or return; + + my ($VideoRAM, $HorizSync, $VertRefresh, $VendorName, $EISA_ID, $size); + for (cat_($xf86log)) { + if (/(VideoRAM|Total Mem): (\d+) kB/) { + $VideoRAM = $2; + } + elsif (/Ranges:\s+V min: (\d+)\s+V max: (\d+) ?Hz,\s+H min: (\d+)\s+H max: (\d+) ?kHz/) { + $HorizSync = "$3-$4"; + $VertRefresh = "$1-$2"; + } + elsif (/hsync range of ([.\d]+-[.\d]+) ?kHz/) { + $HorizSync = $1 if !$HorizSync; + } + elsif (/vrefresh range of ([.\d]+-[.\d]+) ?Hz/) { + $VertRefresh = $1 if !$VertRefresh; + } + elsif (/(Display dimensions|Image Size):\s+\(?(\d+)[,x\s]+(\d+)\)? mm/) { + my ($x, $y) = (($2+9)/10, ($3+9)/10); # round up + $size = sqrt($x*$x + $y*$y) / 2.54 * 1.08; + } + elsif (/Monitor name: (.+)/) { + $VendorName = $1; + } + elsif (/Manufacturer: (\w+)\s+Model: (\w+)/) { + $EISA_ID = "$1$2"; + } + } + + { + VideoRam_probed => $VideoRAM, + HorizSync => $HorizSync, + VertRefresh => $VertRefresh, + size => $size, + if_($EISA_ID, EISA_ID => lc($EISA_ID)), + VendorName => $VendorName || "Plug'n Play", + } +} + sub getinfoFromDDC() { - my ($VideoRam, @l) = any::ddcxinfos() or return; + my ($VideoRam, @l) = any::ddcxinfos() or return getinfoFromXFree(); my @Modes; local $_; @@ -177,6 +218,9 @@ sub getinfoFromDDC() { push @Modes, [ $x, $y, $depth ]; } + # last chance to get some useful information + return getinfoFromXFree() if ! @l; + my ($h, $v, $size, @_modes) = @l; { VideoRam_probed => to_int($VideoRam), @@ -189,13 +233,13 @@ sub getinfoFromDDC() { }; } -sub monitors_db() { +sub monitors() { readMonitorsDB("$ENV{SHARE_PATH}/ldetect-lst/MonitorsDB"); } sub readMonitorsDB { my ($file) = @_; - my @monitors_db; + my @monitors; my $F = openFileMaybeCompressed($file); local $_; my $lineno = 0; while (<$F>) { @@ -206,9 +250,9 @@ sub readMonitorsDB { my @fields = qw(VendorName ModelName EISA_ID HorizSync VertRefresh dpms); my %l; @l{@fields} = split /\s*;\s*/; - push @monitors_db, \%l; + push @monitors, \%l; } - \@monitors_db; + \@monitors; } |