diff options
Diffstat (limited to 'perl-install/Xconfig/monitor.pm')
-rw-r--r-- | perl-install/Xconfig/monitor.pm | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/perl-install/Xconfig/monitor.pm b/perl-install/Xconfig/monitor.pm new file mode 100644 index 000000000..923fc8fb9 --- /dev/null +++ b/perl-install/Xconfig/monitor.pm @@ -0,0 +1,191 @@ +package Xconfig::monitor; #- $Id$ + +use diagnostics; +use strict; + +use detect_devices; +use common; +use any; +use log; + + +my $good_default_monitor = arch() !~ /ppc/ ? 'Generic|1024x768 @ 70 Hz' : + detect_devices::get_mac_model =~ /^iBook/ ? 'Apple|iBook 800x600' : 'Apple|iMac/PowerBook 1024x768'; +my $low_default_monitor = 'Generic|800x600 @ 56 Hz'; + +my @VertRefresh_ranges = ("50-70", "50-90", "50-100", "40-150"); + +my @HorizSync_ranges = ( + "31.5", + "31.5-35.1", + "31.5-37.9", + "31.5-48.5", + "31.5-57.0", + "31.5-64.3", + "31.5-79.0", + "31.5-82.0", + "31.5-88.0", + "31.5-94.0", +); + + +sub from_raw_X { + my ($raw_X) = @_; + + my $monitor = $raw_X->get_monitor; + if (!$monitor->{HorizSync}) { + put_in_hash($monitor, getinfoFromDDC()); + } + $monitor; +} + +sub configure { + my ($in, $raw_X, $auto) = @_; + + my $monitor = from_raw_X($raw_X); + choose($in, $monitor, $auto) or return; + $raw_X->set_monitors($monitor); + $monitor; +} + +sub configure_auto_install { + my ($raw_X, $old_X) = @_; + + my $old_monitor = $old_X->{monitor} || {}; + $old_monitor->{VertRefresh} ||= $old_monitor->{vsyncrange}; + $old_monitor->{HorizSync} ||= $old_monitor->{hsyncrange}; + + my $monitor = from_raw_X($raw_X); + put_in_hash($monitor, $old_monitor); + + my $monitors = monitors(); + configure_automatic($monitor, $monitors) or put_in_hash($monitor, $monitors->{$low_default_monitor}); + $raw_X->set_monitors($monitor); + $monitor; +} + +sub choose { + my ($in, $monitor, $auto) = @_; + + my $monitors = monitors(); + + configure_automatic($monitor, $monitors) and $auto and return 1; + + my $merged_name = do { + if ($monitor->{VendorName} eq "Plug'n Play") { + $monitor->{VendorName}; + } else { + my $merged_name = $monitor->{VendorName} . '|' . $monitor->{ModelName}; + + if (!exists $monitors->{$merged_name}) { + $merged_name = $monitor->{HorizSync} ? 'Custom' : $good_default_monitor; + } + } + }; + + $in->ask_from(_("Monitor"), _("Choose a monitor"), + [ { val => \$merged_name, separator => '|', + list => ['Custom', "Plug'n Play", sort keys %$monitors], + format => sub { $_[0] eq 'Custom' ? _("Custom") : + $_[0] eq "Plug'n Play" ? _("Plug'n Play") . " ($monitor->{ModelName})" : + $_[0] =~ /^Generic\|(.*)/ ? _("Generic") . "|$1" : + _("Vendor") . "|$_[0]" }, + sort => 0 } ]) or return; + + if ($merged_name eq "Plug'n Play") { + local $::noauto = 0; #- hey, you asked for plug'n play, so i do probe! + put_in_hash($monitor, getinfoFromDDC()); + configure_automatic($monitor, $monitors); + $monitor->{VendorName} = "Plug'n Play"; + } elsif ($merged_name eq 'Custom') { + $in->ask_from('', +_("The two critical parameters are the vertical refresh rate, which is the rate +at which the whole screen is refreshed, and most importantly the horizontal +sync rate, which is the rate at which scanlines are displayed. + +It is VERY IMPORTANT that you do not specify a monitor type with a sync range +that is beyond the capabilities of your monitor: you may damage your monitor. + If in doubt, choose a conservative setting."), + [ { val => \$monitor->{HorizSync}, list => \@HorizSync_ranges, label => _("Horizontal refresh rate"), not_edit => 0 }, + { val => \$monitor->{VertRefresh}, list => \@VertRefresh_ranges, label => _("Vertical refresh rate"), not_edit => 0 } ]) or goto &choose; + delete @$monitor{'VendorName', 'ModelName', 'EISA_ID'}; + } else { + put_in_hash($monitor, $monitors->{$merged_name}); + } + $monitor->{manually_chosen} = 1; + 1; +} + +sub configure_automatic { + my ($monitor, $monitors) = @_; + + if ($monitor->{EISA_ID}) { + log::l("EISA_ID: $monitor->{EISA_ID}"); + if (my ($mon) = grep { lc($_->{EISA_ID}) eq $monitor->{EISA_ID} } values %$monitors) { + add2hash($monitor, $mon); + log::l("EISA_ID corresponds to: $monitor->{ModelName}"); + } + } + my $merged_name = $monitor->{VendorName} . '|' . $monitor->{ModelName}; + + put_in_hash($monitor, $monitors->{$merged_name}); + + return $monitor->{HorizSync} && $monitor->{VertRefresh}; +} + +sub getinfoFromDDC { + my ($VideoRam, @l) = any::ddcxinfos() or return; + + my @Modes; + local $_; + while (($_ = shift @l) ne "\n") { + my ($depth, $x, $y) = split; + $depth = int(log($depth) / log(2)); + + push @Modes, [ $x, $y, $depth ]; + } + + my ($h, $v, $size, @m) = @l; + { + VideoRam => $VideoRam, + HorizSync => first($h =~ /^(\S*)/), + VertRefresh => first($v =~ /^(\S*)/), + size => to_float($size), + if_($size =~ /EISA ID=(\S*)/, EISA_ID => lc($1), VendorName => "Plug'n Play"), + #- not-used-anymore Modes => \@Modes, + #- not-used-anymore ModeLines => join('', @m), + }; +} + +sub monitors { + readMonitorsDB("$ENV{SHARE_PATH}/ldetect-lst/MonitorsDB"); +} +sub readMonitorsDB { + my ($file) = @_; + + my (%monitors, %standard_monitors); + + my $F = common::openFileMaybeCompressed($file); + local $_; + my $lineno = 0; while (<$F>) { + $lineno++; + s/\s+$//; + /^#/ and next; + /^$/ and next; + + my @fields = qw(VendorName ModelName EISA_ID HorizSync VertRefresh dpms); + my @l = split /\s*;\s*/; + + my %l; @l{@fields} = @l; + if ($monitors{$l{ModelName}}) { + my $i; for ($i = 0; $monitors{"$l{ModelName} ($i)"}; $i++) {} + $l{ModelName} = "$l{ModelName} ($i)"; + } + $monitors{"$l{VendorName}|$l{ModelName}"} = \%l; + } + \%monitors; +} + + +1; + |