~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/ddc/interpret_edid.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/interpret_edid.c,v 1.7 2000/04/17 16:29:55 eich Exp $ */
 
2
 
 
3
/* interpret_edid.c: interpret a primary EDID block
 
4
 * 
 
5
 * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
 
6
 */
 
7
#ifdef HAVE_XORG_CONFIG_H
 
8
#include <xorg-config.h>
 
9
#endif
 
10
 
 
11
#include "misc.h"
 
12
#include "xf86.h"
 
13
#include "xf86_ansic.h"
 
14
#include "xf86_OSproc.h"
 
15
#define _PARSE_EDID_
 
16
#include "xf86DDC.h"
 
17
 
 
18
static void get_vendor_section(Uchar*, struct vendor *);
 
19
static void get_version_section(Uchar*, struct edid_version *);
 
20
static void get_display_section(Uchar*, struct disp_features *,
 
21
                                struct edid_version *);
 
22
static void get_established_timing_section(Uchar*, struct established_timings *);
 
23
static void get_std_timing_section(Uchar*, struct std_timings *,
 
24
                                   struct edid_version *);
 
25
static void get_dt_md_section(Uchar *, struct edid_version *,
 
26
                              struct detailed_monitor_section *det_mon);
 
27
static void copy_string(Uchar *, Uchar *);
 
28
static void get_dst_timing_section(Uchar *, struct std_timings *,
 
29
                                   struct edid_version *);
 
30
static void get_monitor_ranges(Uchar *, struct monitor_ranges *);
 
31
static void get_whitepoint_section(Uchar *, struct whitePoints *);
 
32
static void get_detailed_timing_section(Uchar*, struct  detailed_timings *);
 
33
static Bool validate_version(int scrnIndex, struct edid_version *);
 
34
 
 
35
 
 
36
xf86MonPtr
 
37
xf86InterpretEDID(int scrnIndex, Uchar *block)
 
38
{
 
39
    xf86MonPtr m;
 
40
 
 
41
    if (!block) return NULL;
 
42
    if (! (m = xnfcalloc(sizeof(xf86Monitor),1))) return NULL;
 
43
    m->scrnIndex = scrnIndex;
 
44
    m->rawData = block;
 
45
 
 
46
    get_vendor_section(SECTION(VENDOR_SECTION,block),&m->vendor);
 
47
    get_version_section(SECTION(VERSION_SECTION,block),&m->ver);
 
48
    if (!validate_version(scrnIndex, &m->ver)) goto error;
 
49
    get_display_section(SECTION(DISPLAY_SECTION,block),&m->features,
 
50
                        &m->ver);
 
51
    get_established_timing_section(SECTION(ESTABLISHED_TIMING_SECTION,block),
 
52
                                   &m->timings1);
 
53
    get_std_timing_section(SECTION(STD_TIMING_SECTION,block),m->timings2,
 
54
                           &m->ver);
 
55
    get_dt_md_section(SECTION(DET_TIMING_SECTION,block),&m->ver, m->det_mon);
 
56
    m->no_sections = (int)*(char *)SECTION(NO_EDID,block);
 
57
    
 
58
    return (m);
 
59
 
 
60
 error:
 
61
    xfree(m);
 
62
    return NULL;
 
63
}
 
64
 
 
65
static void
 
66
get_vendor_section(Uchar *c, struct vendor *r)
 
67
{
 
68
    r->name[0] = L1;
 
69
    r->name[1] = L2;
 
70
    r->name[2] = L3;
 
71
    r->name[3] = '\0';
 
72
  
 
73
    r->prod_id = PROD_ID;
 
74
    r->serial  = SERIAL_NO;
 
75
    r->week    = WEEK;
 
76
    r->year    = YEAR;
 
77
}
 
78
 
 
79
static void 
 
80
get_version_section(Uchar *c, struct edid_version *r)
 
81
{
 
82
    r->version  = VERSION;
 
83
    r->revision = REVISION;
 
84
}
 
85
 
 
86
static void 
 
87
get_display_section(Uchar *c, struct disp_features *r,
 
88
                    struct edid_version *v)
 
89
{
 
90
    r->input_type = INPUT_TYPE;
 
91
    if (!DIGITAL(r->input_type)) {
 
92
        r->input_voltage = INPUT_VOLTAGE;
 
93
        r->input_setup = SETUP;
 
94
        r->input_sync = SYNC;
 
95
    } else if (v->version > 1 || v->revision > 2)
 
96
        r->input_dfp = DFP;
 
97
    r->hsize = HSIZE_MAX;
 
98
    r->vsize = VSIZE_MAX;
 
99
    r->gamma = GAMMA;
 
100
    r->dpms =  DPMS;
 
101
    r->display_type = DISPLAY_TYPE;
 
102
    r->msc = MSC;
 
103
    r->redx = REDX;
 
104
    r->redy = REDY;
 
105
    r->greenx = GREENX;
 
106
    r->greeny = GREENY;
 
107
    r->bluex = BLUEX;
 
108
    r->bluey = BLUEY;
 
109
    r->whitex = WHITEX;
 
110
    r->whitey = WHITEY;
 
111
}
 
112
 
 
113
static void 
 
114
get_established_timing_section(Uchar *c, struct established_timings *r)
 
115
{
 
116
    r->t1 = T1;
 
117
    r->t2 = T2;
 
118
    r->t_manu = T_MANU;
 
119
}
 
120
 
 
121
static void
 
122
get_std_timing_section(Uchar *c, struct std_timings *r,
 
123
                       struct edid_version *v)
 
124
{
 
125
    int i;
 
126
 
 
127
    for (i=0;i<STD_TIMINGS;i++){
 
128
        if (VALID_TIMING) {
 
129
            r[i].hsize = HSIZE1;
 
130
            VSIZE1(r[i].vsize);
 
131
            r[i].refresh = REFRESH_R;
 
132
            r[i].id = STD_TIMING_ID;
 
133
        } else {
 
134
            r[i].hsize = r[i].vsize = r[i].refresh = r[i].id = 0;
 
135
        }
 
136
        NEXT_STD_TIMING;
 
137
    }
 
138
}
 
139
 
 
140
static void
 
141
get_dt_md_section(Uchar *c, struct edid_version *ver, 
 
142
                  struct detailed_monitor_section *det_mon)
 
143
{
 
144
  int i;
 
145
 
 
146
  for (i=0;i<DET_TIMINGS;i++) {  
 
147
    if (ver->version == 1 && ver->revision >= 1 && IS_MONITOR_DESC) {
 
148
 
 
149
      switch (MONITOR_DESC_TYPE) {
 
150
      case SERIAL_NUMBER:
 
151
        det_mon[i].type = DS_SERIAL;
 
152
        copy_string(c,det_mon[i].section.serial);
 
153
        break;
 
154
      case ASCII_STR:
 
155
        det_mon[i].type = DS_ASCII_STR;
 
156
        copy_string(c,det_mon[i].section.ascii_data);
 
157
        break;
 
158
      case MONITOR_RANGES:
 
159
        det_mon[i].type = DS_RANGES;
 
160
        get_monitor_ranges(c,&det_mon[i].section.ranges);
 
161
        break;
 
162
      case MONITOR_NAME:
 
163
        det_mon[i].type = DS_NAME;
 
164
        copy_string(c,det_mon[i].section.name);
 
165
        break;
 
166
      case ADD_COLOR_POINT:
 
167
        det_mon[i].type = DS_WHITE_P;
 
168
        get_whitepoint_section(c,det_mon[i].section.wp);
 
169
        break;
 
170
      case ADD_STD_TIMINGS:
 
171
        det_mon[i].type = DS_STD_TIMINGS;
 
172
        get_dst_timing_section(c,det_mon[i].section.std_t, ver);
 
173
        break;
 
174
      case ADD_DUMMY:
 
175
        det_mon[i].type = DS_DUMMY;
 
176
        break;
 
177
      }
 
178
    } else { 
 
179
      det_mon[i].type = DT;
 
180
      get_detailed_timing_section(c,&det_mon[i].section.d_timings);
 
181
    }
 
182
    NEXT_DT_MD_SECTION;
 
183
  }
 
184
}
 
185
 
 
186
static void
 
187
copy_string(Uchar *c, Uchar *s)
 
188
{
 
189
  int i;
 
190
  c = c + 5;
 
191
  for (i = 0; (i < 13 && *c != 0x0A); i++) 
 
192
    *(s++) = *(c++);
 
193
  *s = 0;
 
194
  while (i-- && (*--s == 0x20)) *s = 0;
 
195
}
 
196
 
 
197
static void
 
198
get_dst_timing_section(Uchar *c, struct std_timings *t,
 
199
                       struct edid_version *v)
 
200
{
 
201
  int j;
 
202
    c = c + 5;
 
203
    for (j = 0; j < 5; j++) {
 
204
        t[j].hsize = HSIZE1;
 
205
        VSIZE1(t[j].vsize);
 
206
        t[j].refresh = REFRESH_R;
 
207
        t[j].id = STD_TIMING_ID;
 
208
        NEXT_STD_TIMING;
 
209
    }
 
210
}
 
211
 
 
212
static void
 
213
get_monitor_ranges(Uchar *c, struct monitor_ranges *r)
 
214
{
 
215
    r->min_v = MIN_V;
 
216
    r->max_v = MAX_V;
 
217
    r->min_h = MIN_H;
 
218
    r->max_h = MAX_H;
 
219
    r->max_clock = 0;
 
220
    if(MAX_CLOCK != 0xff) /* is specified? */
 
221
        r->max_clock = MAX_CLOCK * 10;
 
222
    if (HAVE_2ND_GTF) {
 
223
        r->gtf_2nd_f = F_2ND_GTF;
 
224
        r->gtf_2nd_c = C_2ND_GTF;
 
225
        r->gtf_2nd_m = M_2ND_GTF;
 
226
        r->gtf_2nd_k = K_2ND_GTF;
 
227
        r->gtf_2nd_j = J_2ND_GTF;
 
228
    } else
 
229
        r->gtf_2nd_f = 0;
 
230
}
 
231
 
 
232
static void
 
233
get_whitepoint_section(Uchar *c, struct whitePoints *wp)
 
234
{
 
235
    wp[1].white_x = WHITEX1;
 
236
    wp[1].white_y = WHITEY1;
 
237
    wp[2].white_x = WHITEX2;
 
238
    wp[2].white_y = WHITEY2;
 
239
    wp[1].index  = WHITE_INDEX1;
 
240
    wp[2].index  = WHITE_INDEX2;
 
241
    wp[1].white_gamma  = WHITE_GAMMA1;
 
242
    wp[2].white_gamma  = WHITE_GAMMA2;
 
243
}
 
244
 
 
245
static void
 
246
get_detailed_timing_section(Uchar *c, struct detailed_timings *r)
 
247
{
 
248
  r->clock = PIXEL_CLOCK;
 
249
  r->h_active = H_ACTIVE;
 
250
  r->h_blanking = H_BLANK;
 
251
  r->v_active = V_ACTIVE;
 
252
  r->v_blanking = V_BLANK;
 
253
  r->h_sync_off = H_SYNC_OFF;
 
254
  r->h_sync_width = H_SYNC_WIDTH;
 
255
  r->v_sync_off = V_SYNC_OFF;
 
256
  r->v_sync_width = V_SYNC_WIDTH;
 
257
  r->h_size = H_SIZE;
 
258
  r->v_size = V_SIZE;
 
259
  r->h_border = H_BORDER;
 
260
  r->v_border = V_BORDER;
 
261
  r->interlaced = INTERLACED;
 
262
  r->stereo = STEREO;
 
263
  r->stereo_1 = STEREO1;
 
264
  r->sync = SYNC_T;
 
265
  r->misc = MISC;
 
266
}
 
267
 
 
268
 
 
269
static Bool
 
270
validate_version(int scrnIndex, struct edid_version *r)
 
271
{
 
272
    if (r->version != 1)
 
273
        return FALSE;
 
274
    if (r->revision > 3) {
 
275
        xf86DrvMsg(scrnIndex, X_ERROR,"EDID Version 1.%i not yet supported\n",
 
276
                   r->revision);
 
277
        return FALSE;
 
278
    }
 
279
    return TRUE;
 
280
}