aboutsummaryrefslogtreecommitdiffstats
path: root/monitor-probe-using-X
diff options
context:
space:
mode:
Diffstat (limited to 'monitor-probe-using-X')
-rwxr-xr-xmonitor-probe-using-X133
1 files changed, 133 insertions, 0 deletions
diff --git a/monitor-probe-using-X b/monitor-probe-using-X
new file mode 100755
index 0000000..6e4fdea
--- /dev/null
+++ b/monitor-probe-using-X
@@ -0,0 +1,133 @@
+#!/usr/bin/perl
+
+my ($arg) = @ARGV;
+@ARGV == 1 && $arg !~ /^-/ or die "usage: monitor-probe-using-X <X driver>\n";
+
+my $log;
+if (-e $arg) {
+ #- it is a log file
+ $log = cat_($arg);
+ parse_X_log($log);
+} else {
+ my $Driver = $arg;
+ $log = probe_using_X($Driver) or warn("X probe failed\n"), exit 1;
+
+ my $ok = parse_X_log($log);
+ if ($ENV{DEBUG}) {
+ my $log_file = "/tmp/Xorg.log.$Driver";
+ output($log_file, $log);
+ warn "\n",
+ "Saving log in $log_file.\n",
+ $ok ? "If the detected resolution is wrong" :
+ "If it contains interesting information",
+ ", send $log_file to pixel\@mandrakesoft.com\n\n";
+ }
+ $ok or warn "Could not find a resolution\n";
+}
+
+
+sub cat_ { open(my $F, $_[0]) or return; my @l = <$F>; wantarray() ? @l : join '', @l }
+sub output { my $f = shift; open(my $F, ">$f") or die "output in file $f failed: $!\n"; print $F $_ foreach @_; 1 }
+sub tmpfile() {
+ chomp(my $s = `mktemp /tmp/tmp.XXXXXXXXXX`); #- we could use simply mktemp with new mktemp
+ eval "END { unlink '$s' }";
+ $s;
+}
+sub chvt {
+ my ($vt_number) = @_;
+ my $vt = '';
+ my ($VT_GETSTATE, $VT_ACTIVATE, $VT_WAITACTIVE) = (0x5603, 0x5606, 0x5607);
+ sysopen(my $C, "/dev/console", 2) or die "failed to open /dev/console: $!";
+ ioctl($C, $VT_GETSTATE, $vt) &&
+ ioctl($C, $VT_ACTIVATE, $vt_number) &&
+ ioctl($C, $VT_WAITACTIVE, $vt_number) or die "setVirtual failed";
+ unpack "S", $vt;
+}
+
+sub probe_using_X {
+ my ($Driver) = @_;
+ my $tmp_conf = tmpfile();
+ my $tmp_log = tmpfile();
+
+ output($tmp_conf, <<EOF);
+Section "Device"
+ Identifier "device"
+ Driver "$Driver"
+EndSection
+
+Section "Screen"
+ Identifier "screen"
+ Device "device"
+ DefaultDepth 24
+EndSection
+
+Section "ServerLayout"
+ Identifier "layout"
+ Screen "screen"
+EndSection
+EOF
+
+ my $prev_vt = $Driver eq 'i810' && chvt(1); #- otherwise it can kill existing X
+ alarm 10;
+ my $ok = system("X :67 -ac -probeonly -logfile $tmp_log -config $tmp_conf") == 0;
+ alarm 0;
+ chvt($prev_vt) if $prev_vt;
+
+ if ($ok) {
+ my $log = cat_($tmp_log);
+ return $log;
+ } else {
+ return;
+ }
+}
+
+sub parse_X_log {
+ my ($log) = @_;
+
+ 0
+ # i810 format: "Size of device %s is %d x %d\n" (i810/i830_driver.c)
+ # with one of "CRT", "TV", "DFP (digital flat panel)", "LFP (local flat panel)", "CRT2 (second CRT)", "TV2 (second TV)", "DFP2 (second digital flat panel)", "LFP2 (second local flat panel)",
+ # example: (II) I810(0): Size of device LFP (local flat panel) is 1024 x 768
+ || $log =~ m!\bSize of device LFP \(local flat panel\) is (\d+) x (\d+)$!m
+
+ # ati format: "%dx%d panel (ID %d) detected.\n" (ati/atipreinit.c)
+ # example: (--) ATI(0): 1024x768 panel (ID 3) detected.
+ || $log =~ m!\b(\d+)x(\d+) panel \(ID \d+\) detected\.$!m
+
+ # radeon format: "Panel Size from BIOS: %dx%d\n" (ati/radeon_bios.c)
+ # example: (II) RADEON(0): Panel Size from BIOS: 1400x1050
+ || $log =~ m!\bPanel Size from BIOS: (\d+)x(\d+)$!m
+
+ # nv format: "Panel size is %i x %i\n" (nv/nv_setup.c)
+ # example: (--) NV(0): Panel size is 1280 x 800
+ || $log =~ m!\bPanel size is (\d+) x (\d+)$!m
+
+ # savage format: "%dx%d %s LCD panel detected %s\n" (savage/savage_driver.c)
+ # with one of "TFT", "DSTN", "STN"
+ # and "and active", "but not active"
+ # example: (--) SAVAGE(0): 1024x768 TFT LCD panel detected and active
+ || $log =~ m!\b(\d+)x(\d+) \S+ LCD panel detected !m
+
+ # neomagic format: "Panel is a %dx%d %s %s display\n" (neomagic/neo_driver.c)
+ # with one of "color", "monochrome"
+ # and "TFT", "dual scan"
+ # example: (--) NEOMAGIC(0): Panel is a 1024x768 color TFT display
+ || $log =~ m!\bPanel is a (\d+)x(\d+) (?:color|monochrome) (?:TFT|dual scan) display$!m
+
+ # siliconmotion format: "Detected panel size via BIOS: %d x %d\n" (siliconmotion/smi_driver.c)
+ || $log =~ m!\bDetected panel size via BIOS: (\d+) x (\d+)$!m
+ # siliconmotion format: "%s Panel Size = %dx%d\n" (siliconmotion/smi_driver.c)
+ || $log =~ m! Panel Size = (\d+)x(\d+)$!m
+
+ # trident format: "%s Panel %ix%i found\n" (trident/trident_driver.c)
+ # with one of "TFT", "DSTN", "STN"
+ || $log =~ m!\b(?:TFT|DSTN|STN) Panel (\d+)x(\d+) found$!m
+
+ # via format: "Selected Panel Size is 640x480\n", ... (via/via_driver.c)
+ || $log =~ m!\bSelected Panel Size is (\d+)x(\d+)$!m
+
+ or return;
+
+ print $1, 'x', $2, "\n";
+ 1;
+}