summaryrefslogtreecommitdiffstats
path: root/perl-install/Xconfig/monitor.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/Xconfig/monitor.pm')
-rw-r--r--perl-install/Xconfig/monitor.pm138
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;
}