2 /* edid.c: retrieve EDID record from raw DDC1 data stream: data
3 * is contained in an array of unsigned int each unsigned int
4 * contains one bit if bit is 0 unsigned int has to be zero else
7 * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
9 #ifdef HAVE_XORG_CONFIG_H
10 #include <xorg-config.h>
15 #include "xf86_OSproc.h"
20 static int find_start(unsigned int *);
21 static unsigned char * find_header(unsigned char *);
22 static unsigned char * resort(unsigned char *);
25 GetEDID_DDC1(unsigned int *s_ptr
)
27 unsigned char *d_block
, *d_pos
;
28 unsigned int *s_pos
, *s_end
;
31 s_start
= find_start(s_ptr
);
32 if (s_start
==-1) return NULL
;
34 s_pos
= s_ptr
+ s_start
;
35 d_block
=xalloc(EDID1_LEN
);
36 if (!d_block
) return NULL
;
38 for (i
=0;i
<EDID1_LEN
;i
++) {
44 s_pos
++; if (s_pos
== s_end
) s_pos
=s_ptr
;
46 s_pos
++; if (s_pos
== s_end
) s_pos
=s_ptr
;
50 if (d_block
&& DDC_checksum(d_block
,EDID1_LEN
)) return NULL
;
51 return (resort(d_block
));
55 DDC_checksum(unsigned char *block
, int len
)
66 if (result
& 0xFF) ErrorF("DDC checksum not correct\n");
67 if (!not_null
) ErrorF("DDC read all Null\n");
70 /* catch the trivial case where all bytes are 0 */
71 if (!not_null
) return 1;
77 find_start(unsigned int *ptr
)
79 unsigned int comp
[9], test
[9];
88 test
[j
] = test
[j
] & !(comp
[j
] ^ *(ptr
++));
92 if (test
[i
]) return (i
+1);
96 static unsigned char *
97 find_header(unsigned char *block
)
99 unsigned char *ptr
, *head_ptr
, *end
;
100 unsigned char header
[]={0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
103 end
= block
+ EDID1_LEN
;
108 if (header
[i
] != *(head_ptr
++)) break;
109 if (head_ptr
== end
) head_ptr
= block
;
114 if (ptr
== end
) return (NULL
);
118 static unsigned char *
119 resort(unsigned char *s_block
)
121 unsigned char *d_new
, *d_ptr
, *d_end
, *s_ptr
, *s_end
;
124 s_end
= s_block
+ EDID1_LEN
;
125 d_new
= xalloc(EDID1_LEN
);
126 if (!d_new
) return NULL
;
127 d_end
= d_new
+ EDID1_LEN
;
129 s_ptr
= find_header(s_block
);
130 if (!s_ptr
) return NULL
;
131 for (d_ptr
=d_new
;d_ptr
<d_end
;d_ptr
++){
134 if (s_ptr
== s_end
) s_ptr
= s_block
;