aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnssi Hannula <anssi@mandriva.org>2010-01-02 05:10:29 +0000
committerAnssi Hannula <anssi@mandriva.org>2010-01-02 05:10:29 +0000
commit412da37667cc06fd16b1e28b1b5f20e9a467de8f (patch)
treee3711b6a7883edf6988c7a33d1932d05c9147cc7
parent423de7f72b60fe852c7b07ad80b80b8fcb47880a (diff)
downloadmonitor-edid-412da37667cc06fd16b1e28b1b5f20e9a467de8f.tar
monitor-edid-412da37667cc06fd16b1e28b1b5f20e9a467de8f.tar.gz
monitor-edid-412da37667cc06fd16b1e28b1b5f20e9a467de8f.tar.bz2
monitor-edid-412da37667cc06fd16b1e28b1b5f20e9a467de8f.tar.xz
monitor-edid-412da37667cc06fd16b1e28b1b5f20e9a467de8f.zip
Add handling of EDID extension blocks.
-rw-r--r--NEWS3
-rw-r--r--get-edid.h3
-rw-r--r--monitor-get-edid-using-vbe.c2
-rwxr-xr-xmonitor-parse-edid4
-rw-r--r--vbe.c26
5 files changed, 31 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index af96b80..193e5ab 100644
--- a/NEWS
+++ b/NEWS
@@ -5,8 +5,11 @@
interface on non-x86 hosts as well (fixes Mandriva bug #53866, which
was caused by a bug in the removed code)
o fix the retrieval of VBE vendor strings when using the LRMI interface
+ o retrieve up to 4 EDID extension blocks
+
- monitor-parse-edid:
o print EDID version and the number of EDID extension blocks
+ o accept EDID data with multiple extension blocks
Version 2.5 - 18 October 2009, by Anssi Hannula
diff --git a/get-edid.h b/get-edid.h
index 4b82204..b61dc98 100644
--- a/get-edid.h
+++ b/get-edid.h
@@ -1,3 +1,6 @@
+#define EDID_BLOCK_SIZE 128
+#define MAX_EXTENSION_COUNT 4
+
int verbose;
int get_edid(char *edid, int port);
diff --git a/monitor-get-edid-using-vbe.c b/monitor-get-edid-using-vbe.c
index ba04224..c70e663 100644
--- a/monitor-get-edid-using-vbe.c
+++ b/monitor-get-edid-using-vbe.c
@@ -15,7 +15,7 @@ int verbose = 0;
int main(int argc, char **argv)
{
- char edid[256];
+ char edid[(1 + MAX_EXTENSION_COUNT) * EDID_BLOCK_SIZE];
int try_in_console = 0;
int port = 0;
int i;
diff --git a/monitor-parse-edid b/monitor-parse-edid
index a033c35..68fb32b 100755
--- a/monitor-parse-edid
+++ b/monitor-parse-edid
@@ -487,7 +487,7 @@ sub print_edid {
sub edid_from_lines {
my (@l) = @_;
my $edid_str = join('', map { /\s+([0-9a-f]{32})$/ && $1 } @l);
- length($edid_str) == 256 or return ();
+ length($edid_str) % (2 * 128) == 0 or return ();
pack("C*", map { hex($_) } $edid_str =~ /(..)/g);
}
@@ -536,7 +536,7 @@ sub error {
}
my @raw_edids;
-if (length($input) == 128 || length($input) == 256) {
+if (length($input) % 128 == 0 && length($input) <= 128 * 254) {
@raw_edids = $input;
} else {
@raw_edids = find_edid_in_string($input) or error("bad edid");
diff --git a/vbe.c b/vbe.c
index 8eb74fc..56882d3 100644
--- a/vbe.c
+++ b/vbe.c
@@ -209,11 +209,10 @@ static int vbe_check_ddc_capabilities(int port)
return 1;
}
-static int vbe_get_edid_info(char *edid, int port)
+static int vbe_get_edid_info(char *edid, int port, int block)
{
int i;
unsigned char *mem;
- const int EDID_BLOCK_SIZE = 128;
struct LRMI_regs regs;
/* initialize LRMI */
@@ -235,6 +234,7 @@ static int vbe_get_edid_info(char *edid, int port)
regs.eax = 0x4f15;
regs.ebx = 0x0001;
regs.ecx = port;
+ regs.edx = block;
regs.es = (uintptr_t)(mem - LRMI_base_addr()) >> 4;
regs.edi = (uintptr_t)(mem - LRMI_base_addr()) & 0x0f;
@@ -262,6 +262,7 @@ static int vbe_get_edid_info(char *edid, int port)
int get_edid(char *edid, int port)
{
+ int i, extensions;
int ok = 0;
if (getuid() != 0) {
@@ -272,9 +273,26 @@ int get_edid(char *edid, int port)
ok =
(box_is_xbox() || (vbe_check_vbe_info() &&
vbe_check_ddc_capabilities(port))) &&
- vbe_get_edid_info(edid, port);
+ vbe_get_edid_info(edid, port, 0);
- return ok ? 128 : 0;
+ if (!ok)
+ return 0;
+
+ extensions = ((unsigned char*)edid)[126];
+ if (extensions > MAX_EXTENSION_COUNT) {
+ log_err("EDID: Reported %d extensions, only reading %d\n",
+ extensions, MAX_EXTENSION_COUNT);
+ extensions = MAX_EXTENSION_COUNT;
+ }
+
+ for (i = 1; i <= extensions; i++) {
+ if (!vbe_get_edid_info(edid + i * EDID_BLOCK_SIZE, port, i)) {
+ log_err("EDID: Failure reading extension block %d\n", i);
+ break;
+ }
+ }
+
+ return i * EDID_BLOCK_SIZE;
}
int box_is_xbox() {