First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / ddc / edid.c
blob3ebafbbba5090c837ad57a17000c85db52e722ec
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
5 * unsigned int > 0
6 *
7 * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
8 */
9 #ifdef HAVE_XORG_CONFIG_H
10 #include <xorg-config.h>
11 #endif
13 #include "misc.h"
14 #include "xf86.h"
15 #include "xf86_OSproc.h"
16 #include "xf86DDC.h"
17 #include "ddcPriv.h"
18 #include <string.h>
20 static int find_start(unsigned int *);
21 static unsigned char * find_header(unsigned char *);
22 static unsigned char * resort(unsigned char *);
24 unsigned char *
25 GetEDID_DDC1(unsigned int *s_ptr)
27 unsigned char *d_block, *d_pos;
28 unsigned int *s_pos, *s_end;
29 int s_start;
30 int i,j;
31 s_start = find_start(s_ptr);
32 if (s_start==-1) return NULL;
33 s_end = s_ptr + NUM;
34 s_pos = s_ptr + s_start;
35 d_block=xalloc(EDID1_LEN);
36 if (!d_block) return NULL;
37 d_pos = d_block;
38 for (i=0;i<EDID1_LEN;i++) {
39 for (j=0;j<8;j++) {
40 *d_pos <<= 1;
41 if (*s_pos) {
42 *d_pos |= 0x01;
44 s_pos++; if (s_pos == s_end) s_pos=s_ptr;
46 s_pos++; if (s_pos == s_end) s_pos=s_ptr;
47 d_pos++;
49 xfree(s_ptr);
50 if (d_block && DDC_checksum(d_block,EDID1_LEN)) return NULL;
51 return (resort(d_block));
54 int
55 DDC_checksum(unsigned char *block, int len)
57 int i, result = 0;
58 int not_null = 0;
60 for (i=0;i<len;i++) {
61 not_null |= block[i];
62 result += block[i];
65 #ifdef DEBUG
66 if (result & 0xFF) ErrorF("DDC checksum not correct\n");
67 if (!not_null) ErrorF("DDC read all Null\n");
68 #endif
70 /* catch the trivial case where all bytes are 0 */
71 if (!not_null) return 1;
73 return (result&0xFF);
76 static int
77 find_start(unsigned int *ptr)
79 unsigned int comp[9], test[9];
80 int i,j;
82 for (i=0;i<9;i++){
83 comp[i] = *(ptr++);
84 test[i] = 1;
86 for (i=0;i<127;i++){
87 for (j=0;j<9;j++){
88 test[j] = test[j] & !(comp[j] ^ *(ptr++));
91 for (i=0;i<9;i++)
92 if (test[i]) return (i+1);
93 return (-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};
102 ptr = block;
103 end = block + EDID1_LEN;
104 while (ptr<end) {
105 int i;
106 head_ptr = ptr;
107 for (i=0;i<8;i++){
108 if (header[i] != *(head_ptr++)) break;
109 if (head_ptr == end) head_ptr = block;
111 if (i==8) break;
112 ptr++;
114 if (ptr == end) return (NULL);
115 return (ptr);
118 static unsigned char *
119 resort(unsigned char *s_block)
121 unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end;
122 unsigned char tmp;
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++){
132 tmp = *(s_ptr++);
133 *d_ptr = tmp;
134 if (s_ptr == s_end) s_ptr = s_block;
136 xfree(s_block);
137 return (d_new);