1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#!/usr/bin/perl
# Copyright (C) 2005-2010 by Mandriva SA
# Pascal Rigaux
# Anssi Hannula
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use Getopt::Long;
use Parse::EDID;
GetOptions(
'v' => \ (my $verbose),
'perl' => \ (my $raw_perl),
'MonitorsDB' => \ (my $MonitorsDB),
) or usage();
my ($file, $F);
if (@ARGV == 0) {
$F = *STDIN;
} elsif (@ARGV == 1) {
open($F, $file = $ARGV[0]) or usage();
} else {
usage();
}
my $input = join('', <$F>);
my @raw_edids;
my $length = length($input);
if ($length % 128 == 0 && $length >= 128 && $length <= 128 * 254) {
@raw_edids = $input;
} else {
@raw_edids = find_edid_in_string($input) or error("bad edid");
}
foreach my $raw_edid (@raw_edids) {
my $edid = parse_edid($raw_edid, $verbose);
if (my $err = check_parsed_edid($edid)) {
die "$err\n";
}
$edid->{file} = $file if $file;
if ($raw_perl) {
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
my $s = Dumper($edid);
$s =~ s/.*? = \{/+{/; # remove variable name we don't want
$s =~ s/};$/}/m;
print $s;
} elsif ($MonitorsDB) {
my $s = to_MonitorsDB($edid);
print "$s\n" if $s;
} else {
print_edid($edid, $verbose);
}
}
sub usage() {
die <<'EOF';
usage: monitor-parse-edid [-v] [--perl] [<edid file>]
You can also do "xrandr --prop | monitor-parse-edid"
EOF
}
sub error {
my ($msg) = @_;
print STDERR ($file ? "$file: " : ''), $msg, "\n";
exit 1;
}
sub print_edid {
my ($edid, $verbose) = @_;
print "Name: $edid->{monitor_name}\n" if $edid->{monitor_name};
print "EISA ID: $edid->{EISA_ID}\n" if $edid->{EISA_ID};
print "EDID version: $edid->{edid_version}.$edid->{edid_revision}\n";
# this is a number, despite the official name containing "flag":
print "EDID extension blocks: $edid->{extension_flag}\n";
printf "Screen size: %.1f cm x %.1f cm (%3.2f inches%s)\n",
$edid->{max_size_horizontal},
$edid->{max_size_vertical},
$edid->{diagonal_size},
$edid->{ratio_name} ? sprintf(", aspect ratio %s = %.2f", $edid->{ratio_name}, $edid->{ratio}) :
$edid->{ratio} ? sprintf(", aspect ratio %.2f", $edid->{ratio}) : '';
print "Gamma: ", $edid->{gamma} / 100 + 1, "\n";
printf "%s signal\n", $edid->{video_input_definition}{digital} ? 'Digital' : 'Analog';
if ($verbose) {
foreach (@{$edid->{established_timings} || []}) {
print "Standard resolution: $_->{X}x$_->{Y} @ $_->{vfreq} Hz (established timing)\n" if !$_->{interlace};
}
foreach (@{$edid->{standard_timings} || []}) {
print "Standard resolution: $_->{X}x$_->{Y} @ $_->{vfreq} Hz, ratio $_->{ratio}",
$edid->{ratio_name} && index($edid->{ratio_name}, $_->{ratio}) == -1 ? ' (!)' : '',
"\n";
}
}
if ($edid->{monitor_range}) {
printf "Max video bandwidth: %u MHz\n", $edid->{monitor_range}{pixel_clock_max} if $edid->{monitor_range}{pixel_clock_max};
print "\n";
printf "\tHorizSync %u-%u\n", $edid->{monitor_range}{horizontal_min}, $edid->{monitor_range}{horizontal_max};
printf "\tVertRefresh %u-%u\n", $edid->{monitor_range}{vertical_min}, $edid->{monitor_range}{vertical_max};
}
foreach my $h (@{$edid->{detailed_timings}}) {
print "\n";
print "\t", $h->{ModeLine_comment}, $h->{bad_ratio} ? ' (bad ratio)' : '', "\n";
print "\tModeLine ", $h->{ModeLine}, "\n";
}
}
|