1
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/edid.c,v 1.4 2003/02/17 16:08:27 dawes Exp $ */
3
/* edid.c: retrieve EDID record from raw DDC1 data stream: data
4
* is contained in an array of unsigned int each unsigned int
5
* contains one bit if bit is 0 unsigned int has to be zero else
8
* Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
12
#include "xf86_ansic.h"
13
#include "xf86_OSproc.h"
17
static int find_start(unsigned int *);
18
static unsigned char * find_header(unsigned char *);
19
static unsigned char * resort(unsigned char *);
22
GetEDID_DDC1(unsigned int *s_ptr)
24
unsigned char *d_block, *d_pos;
25
unsigned int *s_pos, *s_end;
28
s_start = find_start(s_ptr);
29
if (s_start==-1) return NULL;
31
s_pos = s_ptr + s_start;
32
d_block=xalloc(EDID1_LEN);
33
if (!d_block) return NULL;
35
for (i=0;i<EDID1_LEN;i++) {
41
s_pos++; if (s_pos == s_end) s_pos=s_ptr;
43
s_pos++; if (s_pos == s_end) s_pos=s_ptr;
47
if (d_block && DDC_checksum(d_block,EDID1_LEN)) return NULL;
48
return (resort(d_block));
52
DDC_checksum(unsigned char *block, int len)
63
if (result & 0xFF) ErrorF("DDC checksum not correct\n");
64
if (!not_null) ErrorF("DDC read all Null\n");
67
/* catch the trivial case where all bytes are 0 */
68
if (!not_null) return 1;
74
find_start(unsigned int *ptr)
76
unsigned int comp[9], test[9];
85
test[j] = test[j] & !(comp[j] ^ *(ptr++));
89
if (test[i]) return (i+1);
93
static unsigned char *
94
find_header(unsigned char *block)
96
unsigned char *ptr, *head_ptr, *end;
97
unsigned char header[]={0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
100
end = block + EDID1_LEN;
105
if (header[i] != *(head_ptr++)) break;
106
if (head_ptr == end) head_ptr = block;
111
if (ptr == end) return (NULL);
115
static unsigned char *
116
resort(unsigned char *s_block)
118
unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end;
121
s_end = s_block + EDID1_LEN;
122
d_new = xalloc(EDID1_LEN);
123
if (!d_new) return NULL;
124
d_end = d_new + EDID1_LEN;
126
s_ptr = find_header(s_block);
127
if (!s_ptr) return NULL;
128
for (d_ptr=d_new;d_ptr<d_end;d_ptr++){
131
if (s_ptr == s_end) s_ptr = s_block;