SDL  2.0
edid-parse.c File Reference
#include "../../SDL_internal.h"
#include "SDL_stdinc.h"
#include "edid.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
+ Include dependency graph for edid-parse.c:

Go to the source code of this file.

Macros

#define TRUE   1
 
#define FALSE   0
 

Functions

static int get_bit (int in, int bit)
 
static int get_bits (int in, int begin, int end)
 
static int decode_header (const uchar *edid)
 
static int decode_vendor_and_product_identification (const uchar *edid, MonitorInfo *info)
 
static int decode_edid_version (const uchar *edid, MonitorInfo *info)
 
static int decode_display_parameters (const uchar *edid, MonitorInfo *info)
 
static double decode_fraction (int high, int low)
 
static int decode_color_characteristics (const uchar *edid, MonitorInfo *info)
 
static int decode_established_timings (const uchar *edid, MonitorInfo *info)
 
static int decode_standard_timings (const uchar *edid, MonitorInfo *info)
 
static void decode_lf_string (const uchar *s, int n_chars, char *result)
 
static void decode_display_descriptor (const uchar *desc, MonitorInfo *info)
 
static void decode_detailed_timing (const uchar *timing, DetailedTiming *detailed)
 
static int decode_descriptors (const uchar *edid, MonitorInfo *info)
 
static void decode_check_sum (const uchar *edid, MonitorInfo *info)
 
MonitorInfodecode_edid (const uchar *edid)
 
static const char * yesno (int v)
 
void dump_monitor_info (MonitorInfo *info)
 

Macro Definition Documentation

◆ FALSE

#define FALSE   0

◆ TRUE

Function Documentation

◆ decode_check_sum()

static void decode_check_sum ( const uchar edid,
MonitorInfo info 
)
static

Definition at line 510 of file edid-parse.c.

References MonitorInfo::checksum, and i.

Referenced by decode_edid().

512 {
513  int i;
514  uchar check = 0;
515 
516  for (i = 0; i < 128; ++i)
517  check += edid[i];
518 
519  info->checksum = check;
520 }
int checksum
Definition: edid.h:82
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
unsigned char uchar
Definition: edid.h:1

◆ decode_color_characteristics()

static int decode_color_characteristics ( const uchar edid,
MonitorInfo info 
)
static

Definition at line 258 of file edid-parse.c.

References MonitorInfo::blue_x, MonitorInfo::blue_y, decode_fraction(), get_bits(), MonitorInfo::green_x, MonitorInfo::green_y, MonitorInfo::red_x, MonitorInfo::red_y, TRUE, MonitorInfo::white_x, and MonitorInfo::white_y.

Referenced by decode_edid().

259 {
260  info->red_x = decode_fraction (edid[0x1b], get_bits (edid[0x19], 6, 7));
261  info->red_y = decode_fraction (edid[0x1c], get_bits (edid[0x19], 5, 4));
262  info->green_x = decode_fraction (edid[0x1d], get_bits (edid[0x19], 2, 3));
263  info->green_y = decode_fraction (edid[0x1e], get_bits (edid[0x19], 0, 1));
264  info->blue_x = decode_fraction (edid[0x1f], get_bits (edid[0x1a], 6, 7));
265  info->blue_y = decode_fraction (edid[0x20], get_bits (edid[0x1a], 4, 5));
266  info->white_x = decode_fraction (edid[0x21], get_bits (edid[0x1a], 2, 3));
267  info->white_y = decode_fraction (edid[0x22], get_bits (edid[0x1a], 0, 1));
268 
269  return TRUE;
270 }
double green_y
Definition: edid.h:140
static int get_bits(int in, int begin, int end)
Definition: edid-parse.c:43
double white_y
Definition: edid.h:144
double red_x
Definition: edid.h:137
double blue_x
Definition: edid.h:141
static double decode_fraction(int high, int low)
Definition: edid-parse.c:244
#define TRUE
Definition: edid-parse.c:33
double white_x
Definition: edid.h:143
double green_x
Definition: edid.h:139
double blue_y
Definition: edid.h:142
double red_y
Definition: edid.h:138

◆ decode_descriptors()

static int decode_descriptors ( const uchar edid,
MonitorInfo info 
)
static

Definition at line 482 of file edid-parse.c.

References decode_detailed_timing(), decode_display_descriptor(), MonitorInfo::detailed_timings, i, MonitorInfo::n_detailed_timings, and TRUE.

Referenced by decode_edid().

483 {
484  int i;
485  int timing_idx;
486 
487  timing_idx = 0;
488 
489  for (i = 0; i < 4; ++i)
490  {
491  int index = 0x36 + i * 18;
492 
493  if (edid[index + 0] == 0x00 && edid[index + 1] == 0x00)
494  {
495  decode_display_descriptor (edid + index, info);
496  }
497  else
498  {
500  edid + index, &(info->detailed_timings[timing_idx++]));
501  }
502  }
503 
504  info->n_detailed_timings = timing_idx;
505 
506  return TRUE;
507 }
int n_detailed_timings
Definition: edid.h:149
static void decode_detailed_timing(const uchar *timing, DetailedTiming *detailed)
Definition: edid-parse.c:419
static void decode_display_descriptor(const uchar *desc, MonitorInfo *info)
Definition: edid-parse.c:381
#define TRUE
Definition: edid-parse.c:33
GLuint index
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
DetailedTiming detailed_timings[4]
Definition: edid.h:150

◆ decode_detailed_timing()

static void decode_detailed_timing ( const uchar timing,
DetailedTiming detailed 
)
static

Definition at line 419 of file edid-parse.c.

References DetailedTiming::ad, DetailedTiming::analog, DetailedTiming::digital, DetailedTiming::digital_sync, FALSE, FIELD_LEFT, FIELD_RIGHT, FOUR_WAY_INTERLEAVED, get_bit(), get_bits(), DetailedTiming::h_addr, DetailedTiming::h_blank, DetailedTiming::h_front_porch, DetailedTiming::h_sync, DetailedTiming::height_mm, DetailedTiming::interlaced, NO_STEREO, DetailedTiming::pixel_clock, DetailedTiming::right_border, SIDE_BY_SIDE, DetailedTiming::stereo, DetailedTiming::top_border, TWO_WAY_LEFT_ON_EVEN, TWO_WAY_RIGHT_ON_EVEN, DetailedTiming::v_addr, DetailedTiming::v_blank, DetailedTiming::v_front_porch, DetailedTiming::v_sync, and DetailedTiming::width_mm.

Referenced by decode_descriptors().

421 {
422  int bits;
423  StereoType stereo[] =
424  {
428  };
429 
430  detailed->pixel_clock = (timing[0x00] | timing[0x01] << 8) * 10000;
431  detailed->h_addr = timing[0x02] | ((timing[0x04] & 0xf0) << 4);
432  detailed->h_blank = timing[0x03] | ((timing[0x04] & 0x0f) << 8);
433  detailed->v_addr = timing[0x05] | ((timing[0x07] & 0xf0) << 4);
434  detailed->v_blank = timing[0x06] | ((timing[0x07] & 0x0f) << 8);
435  detailed->h_front_porch = timing[0x08] | get_bits (timing[0x0b], 6, 7) << 8;
436  detailed->h_sync = timing[0x09] | get_bits (timing[0x0b], 4, 5) << 8;
437  detailed->v_front_porch =
438  get_bits (timing[0x0a], 4, 7) | get_bits (timing[0x0b], 2, 3) << 4;
439  detailed->v_sync =
440  get_bits (timing[0x0a], 0, 3) | get_bits (timing[0x0b], 0, 1) << 4;
441  detailed->width_mm = timing[0x0c] | get_bits (timing[0x0e], 4, 7) << 8;
442  detailed->height_mm = timing[0x0d] | get_bits (timing[0x0e], 0, 3) << 8;
443  detailed->right_border = timing[0x0f];
444  detailed->top_border = timing[0x10];
445 
446  detailed->interlaced = get_bit (timing[0x11], 7);
447 
448  /* Stereo */
449  bits = get_bits (timing[0x11], 5, 6) << 1 | get_bit (timing[0x11], 0);
450  detailed->stereo = stereo[bits];
451 
452  /* Sync */
453  bits = timing[0x11];
454 
455  detailed->digital_sync = get_bit (bits, 4);
456  if (detailed->digital_sync)
457  {
458  detailed->ad.digital.composite = !get_bit (bits, 3);
459 
460  if (detailed->ad.digital.composite)
461  {
462  detailed->ad.digital.serrations = get_bit (bits, 2);
463  detailed->ad.digital.negative_vsync = FALSE;
464  }
465  else
466  {
467  detailed->ad.digital.serrations = FALSE;
468  detailed->ad.digital.negative_vsync = !get_bit (bits, 2);
469  }
470 
471  detailed->ad.digital.negative_hsync = !get_bit (bits, 0);
472  }
473  else
474  {
475  detailed->ad.analog.bipolar = get_bit (bits, 3);
476  detailed->ad.analog.serrations = get_bit (bits, 2);
477  detailed->ad.analog.sync_on_green = !get_bit (bits, 1);
478  }
479 }
int h_sync
Definition: edid.h:47
int h_front_porch
Definition: edid.h:48
static int get_bits(int in, int begin, int end)
Definition: edid-parse.c:43
int interlaced
Definition: edid.h:57
int height_mm
Definition: edid.h:54
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
int pixel_clock
Definition: edid.h:44
struct DetailedTiming::@44::@45 analog
static int get_bit(int in, int bit)
Definition: edid-parse.c:37
int digital_sync
Definition: edid.h:60
int top_border
Definition: edid.h:56
int right_border
Definition: edid.h:55
struct DetailedTiming::@44::@46 digital
int v_front_porch
Definition: edid.h:52
StereoType
Definition: edid.h:24
int v_addr
Definition: edid.h:49
int h_addr
Definition: edid.h:45
int v_sync
Definition: edid.h:51
union DetailedTiming::@44 ad
StereoType stereo
Definition: edid.h:58
int width_mm
Definition: edid.h:53
int v_blank
Definition: edid.h:50
Definition: edid.h:26
#define FALSE
Definition: edid-parse.c:34
int h_blank
Definition: edid.h:46

◆ decode_display_descriptor()

static void decode_display_descriptor ( const uchar desc,
MonitorInfo info 
)
static

Definition at line 381 of file edid-parse.c.

References decode_lf_string(), MonitorInfo::dsc_product_name, MonitorInfo::dsc_serial_number, and MonitorInfo::dsc_string.

Referenced by decode_descriptors().

383 {
384  switch (desc[0x03])
385  {
386  case 0xFC:
387  decode_lf_string (desc + 5, 13, info->dsc_product_name);
388  break;
389  case 0xFF:
390  decode_lf_string (desc + 5, 13, info->dsc_serial_number);
391  break;
392  case 0xFE:
393  decode_lf_string (desc + 5, 13, info->dsc_string);
394  break;
395  case 0xFD:
396  /* Range Limits */
397  break;
398  case 0xFB:
399  /* Color Point */
400  break;
401  case 0xFA:
402  /* Timing Identifications */
403  break;
404  case 0xF9:
405  /* Color Management */
406  break;
407  case 0xF8:
408  /* Timing Codes */
409  break;
410  case 0xF7:
411  /* Established Timings */
412  break;
413  case 0x10:
414  break;
415  }
416 }
char dsc_product_name[14]
Definition: edid.h:160
static void decode_lf_string(const uchar *s, int n_chars, char *result)
Definition: edid-parse.c:358
char dsc_string[14]
Definition: edid.h:161
char dsc_serial_number[14]
Definition: edid.h:159

◆ decode_display_parameters()

static int decode_display_parameters ( const uchar edid,
MonitorInfo info 
)
static

Definition at line 123 of file edid-parse.c.

References MonitorInfo::active_off, MonitorInfo::ad, MonitorInfo::analog, MonitorInfo::aspect_ratio, MonitorInfo::continuous_frequency, MonitorInfo::digital, DISPLAY_PORT, DVI, MonitorInfo::gamma, get_bit(), get_bits(), HDMI_A, HDMI_B, MonitorInfo::height_mm, MonitorInfo::is_digital, MDDI, MONOCHROME, OTHER_COLOR, MonitorInfo::preferred_timing_includes_native, RGB, MonitorInfo::srgb_is_standard, MonitorInfo::standby, MonitorInfo::suspend, TRUE, UNDEFINED, UNDEFINED_COLOR, and MonitorInfo::width_mm.

Referenced by decode_edid().

124 {
125  /* Digital vs Analog */
126  info->is_digital = get_bit (edid[0x14], 7);
127 
128  if (info->is_digital)
129  {
130  int bits;
131 
132  static const int bit_depth[8] =
133  {
134  -1, 6, 8, 10, 12, 14, 16, -1
135  };
136 
137  static const Interface interfaces[6] =
138  {
140  };
141 
142  bits = get_bits (edid[0x14], 4, 6);
143  info->ad.digital.bits_per_primary = bit_depth[bits];
144 
145  bits = get_bits (edid[0x14], 0, 3);
146 
147  if (bits <= 5)
148  info->ad.digital.interface = interfaces[bits];
149  else
150  info->ad.digital.interface = UNDEFINED;
151  }
152  else
153  {
154  int bits = get_bits (edid[0x14], 5, 6);
155 
156  static const double levels[][3] =
157  {
158  { 0.7, 0.3, 1.0 },
159  { 0.714, 0.286, 1.0 },
160  { 1.0, 0.4, 1.4 },
161  { 0.7, 0.0, 0.7 },
162  };
163 
164  info->ad.analog.video_signal_level = levels[bits][0];
165  info->ad.analog.sync_signal_level = levels[bits][1];
166  info->ad.analog.total_signal_level = levels[bits][2];
167 
168  info->ad.analog.blank_to_black = get_bit (edid[0x14], 4);
169 
170  info->ad.analog.separate_hv_sync = get_bit (edid[0x14], 3);
171  info->ad.analog.composite_sync_on_h = get_bit (edid[0x14], 2);
172  info->ad.analog.composite_sync_on_green = get_bit (edid[0x14], 1);
173 
174  info->ad.analog.serration_on_vsync = get_bit (edid[0x14], 0);
175  }
176 
177  /* Screen Size / Aspect Ratio */
178  if (edid[0x15] == 0 && edid[0x16] == 0)
179  {
180  info->width_mm = -1;
181  info->height_mm = -1;
182  info->aspect_ratio = -1.0;
183  }
184  else if (edid[0x16] == 0)
185  {
186  info->width_mm = -1;
187  info->height_mm = -1;
188  info->aspect_ratio = 100.0 / (edid[0x15] + 99);
189  }
190  else if (edid[0x15] == 0)
191  {
192  info->width_mm = -1;
193  info->height_mm = -1;
194  info->aspect_ratio = 100.0 / (edid[0x16] + 99);
195  info->aspect_ratio = 1/info->aspect_ratio; /* portrait */
196  }
197  else
198  {
199  info->width_mm = 10 * edid[0x15];
200  info->height_mm = 10 * edid[0x16];
201  }
202 
203  /* Gamma */
204  if (edid[0x17] == 0xFF)
205  info->gamma = -1.0;
206  else
207  info->gamma = (edid[0x17] + 100.0) / 100.0;
208 
209  /* Features */
210  info->standby = get_bit (edid[0x18], 7);
211  info->suspend = get_bit (edid[0x18], 6);
212  info->active_off = get_bit (edid[0x18], 5);
213 
214  if (info->is_digital)
215  {
216  info->ad.digital.rgb444 = TRUE;
217  if (get_bit (edid[0x18], 3))
218  info->ad.digital.ycrcb444 = 1;
219  if (get_bit (edid[0x18], 4))
220  info->ad.digital.ycrcb422 = 1;
221  }
222  else
223  {
224  int bits = get_bits (edid[0x18], 3, 4);
225  ColorType color_type[4] =
226  {
228  };
229 
230  info->ad.analog.color_type = color_type[bits];
231  }
232 
233  info->srgb_is_standard = get_bit (edid[0x18], 2);
234 
235  /* In 1.3 this is called "has preferred timing" */
236  info->preferred_timing_includes_native = get_bit (edid[0x18], 1);
237 
238  /* FIXME: In 1.3 this indicates whether the monitor accepts GTF */
239  info->continuous_frequency = get_bit (edid[0x18], 0);
240  return TRUE;
241 }
Definition: edid.h:20
static int get_bits(int in, int begin, int end)
Definition: edid-parse.c:43
Definition: edid.h:8
int active_off
Definition: edid.h:131
int suspend
Definition: edid.h:130
int standby
Definition: edid.h:129
ColorType
Definition: edid.h:16
Definition: edid.h:10
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
struct MonitorInfo::@47::@49 analog
int width_mm
Definition: edid.h:123
static int get_bit(int in, int bit)
Definition: edid-parse.c:37
Definition: edid.h:11
#define TRUE
Definition: edid-parse.c:33
Definition: edid.h:12
int continuous_frequency
Definition: edid.h:135
double aspect_ratio
Definition: edid.h:125
int preferred_timing_includes_native
Definition: edid.h:134
GLsizei levels
int srgb_is_standard
Definition: edid.h:133
int is_digital
Definition: edid.h:94
int height_mm
Definition: edid.h:124
Definition: edid.h:9
double gamma
Definition: edid.h:127
struct MonitorInfo::@47::@48 digital
union MonitorInfo::@47 ad
Interface
Definition: edid.h:6

◆ decode_edid()

MonitorInfo* decode_edid ( const uchar edid)

Definition at line 523 of file edid-parse.c.

References decode_check_sum(), decode_color_characteristics(), decode_descriptors(), decode_display_parameters(), decode_edid_version(), decode_established_timings(), decode_header(), decode_standard_timings(), decode_vendor_and_product_identification(), free, and NULL.

524 {
525  MonitorInfo *info = calloc (1, sizeof (MonitorInfo));
526 
527  decode_check_sum (edid, info);
528 
529  if (!decode_header (edid) ||
531  !decode_edid_version (edid, info) ||
532  !decode_display_parameters (edid, info) ||
533  !decode_color_characteristics (edid, info) ||
534  !decode_established_timings (edid, info) ||
535  !decode_standard_timings (edid, info) ||
536  !decode_descriptors (edid, info)) {
537  free(info);
538  return NULL;
539  }
540 
541  return info;
542 }
static int decode_color_characteristics(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:258
static int decode_header(const uchar *edid)
Definition: edid-parse.c:51
SDL_EventEntry * free
Definition: SDL_events.c:84
static int decode_edid_version(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:114
static int decode_established_timings(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:273
static void decode_check_sum(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:510
static int decode_display_parameters(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:123
static int decode_vendor_and_product_identification(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:59
#define NULL
Definition: begin_code.h:164
static int decode_descriptors(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:482
static int decode_standard_timings(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:326

◆ decode_edid_version()

static int decode_edid_version ( const uchar edid,
MonitorInfo info 
)
static

Definition at line 114 of file edid-parse.c.

References MonitorInfo::major_version, MonitorInfo::minor_version, and TRUE.

Referenced by decode_edid().

115 {
116  info->major_version = edid[0x12];
117  info->minor_version = edid[0x13];
118 
119  return TRUE;
120 }
int minor_version
Definition: edid.h:92
int major_version
Definition: edid.h:91
#define TRUE
Definition: edid-parse.c:33

◆ decode_established_timings()

static int decode_established_timings ( const uchar edid,
MonitorInfo info 
)
static

Definition at line 273 of file edid-parse.c.

References MonitorInfo::established, get_bit(), i, idx, j, and TRUE.

Referenced by decode_edid().

274 {
275  static const Timing established[][8] =
276  {
277  {
278  { 800, 600, 60 },
279  { 800, 600, 56 },
280  { 640, 480, 75 },
281  { 640, 480, 72 },
282  { 640, 480, 67 },
283  { 640, 480, 60 },
284  { 720, 400, 88 },
285  { 720, 400, 70 }
286  },
287  {
288  { 1280, 1024, 75 },
289  { 1024, 768, 75 },
290  { 1024, 768, 70 },
291  { 1024, 768, 60 },
292  { 1024, 768, 87 },
293  { 832, 624, 75 },
294  { 800, 600, 75 },
295  { 800, 600, 72 }
296  },
297  {
298  { 0, 0, 0 },
299  { 0, 0, 0 },
300  { 0, 0, 0 },
301  { 0, 0, 0 },
302  { 0, 0, 0 },
303  { 0, 0, 0 },
304  { 0, 0, 0 },
305  { 1152, 870, 75 }
306  },
307  };
308 
309  int i, j, idx;
310 
311  idx = 0;
312  for (i = 0; i < 3; ++i)
313  {
314  for (j = 0; j < 8; ++j)
315  {
316  int byte = edid[0x23 + i];
317 
318  if (get_bit (byte, j) && established[i][j].frequency != 0)
319  info->established[idx++] = established[i][j];
320  }
321  }
322  return TRUE;
323 }
Definition: edid.h:35
static int get_bit(int in, int bit)
Definition: edid-parse.c:37
#define TRUE
Definition: edid-parse.c:33
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:50
Timing established[24]
Definition: edid.h:146
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 idx

◆ decode_fraction()

static double decode_fraction ( int  high,
int  low 
)
static

Definition at line 244 of file edid-parse.c.

References get_bit(), i, and SDL_pow.

Referenced by decode_color_characteristics().

245 {
246  double result = 0.0;
247  int i;
248 
249  high = (high << 2) | low;
250 
251  for (i = 0; i < 10; ++i)
252  result += get_bit (high, i) * SDL_pow (2, i - 10);
253 
254  return result;
255 }
GLuint64EXT * result
static int get_bit(int in, int bit)
Definition: edid-parse.c:37
#define SDL_pow
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50

◆ decode_header()

static int decode_header ( const uchar edid)
static

Definition at line 51 of file edid-parse.c.

References FALSE, and TRUE.

Referenced by decode_edid().

52 {
53  if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0)
54  return TRUE;
55  return FALSE;
56 }
#define TRUE
Definition: edid-parse.c:33
#define FALSE
Definition: edid-parse.c:34

◆ decode_lf_string()

static void decode_lf_string ( const uchar s,
int  n_chars,
char *  result 
)
static

Definition at line 358 of file edid-parse.c.

References i.

Referenced by decode_display_descriptor().

359 {
360  int i;
361  for (i = 0; i < n_chars; ++i)
362  {
363  if (s[i] == 0x0a)
364  {
365  *result++ = '\0';
366  break;
367  }
368  else if (s[i] == 0x00)
369  {
370  /* Convert embedded 0's to spaces */
371  *result++ = ' ';
372  }
373  else
374  {
375  *result++ = s[i];
376  }
377  }
378 }
GLuint64EXT * result
GLdouble s
Definition: SDL_opengl.h:2063
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50

◆ decode_standard_timings()

static int decode_standard_timings ( const uchar edid,
MonitorInfo info 
)
static

Definition at line 326 of file edid-parse.c.

References Timing::frequency, get_bits(), Timing::height, i, MonitorInfo::standard, TRUE, and Timing::width.

Referenced by decode_edid().

327 {
328  int i;
329 
330  for (i = 0; i < 8; i++)
331  {
332  int first = edid[0x26 + 2 * i];
333  int second = edid[0x27 + 2 * i];
334 
335  if (first != 0x01 && second != 0x01)
336  {
337  int w = 8 * (first + 31);
338  int h = 0;
339 
340  switch (get_bits (second, 6, 7))
341  {
342  case 0x00: h = (w / 16) * 10; break;
343  case 0x01: h = (w / 4) * 3; break;
344  case 0x02: h = (w / 5) * 4; break;
345  case 0x03: h = (w / 16) * 9; break;
346  }
347 
348  info->standard[i].width = w;
349  info->standard[i].height = h;
350  info->standard[i].frequency = get_bits (second, 0, 5) + 60;
351  }
352  }
353 
354  return TRUE;
355 }
int frequency
Definition: edid.h:39
int height
Definition: edid.h:38
static int get_bits(int in, int begin, int end)
Definition: edid-parse.c:43
const GLint * first
GLfloat GLfloat GLfloat GLfloat h
int width
Definition: edid.h:37
Timing standard[8]
Definition: edid.h:147
#define TRUE
Definition: edid-parse.c:33
GLubyte GLubyte GLubyte GLubyte w
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50

◆ decode_vendor_and_product_identification()

static int decode_vendor_and_product_identification ( const uchar edid,
MonitorInfo info 
)
static

Definition at line 59 of file edid-parse.c.

References FALSE, get_bits(), MonitorInfo::manufacturer_code, MonitorInfo::model_year, MonitorInfo::product_code, MonitorInfo::production_week, MonitorInfo::production_year, MonitorInfo::serial_number, and TRUE.

Referenced by decode_edid().

60 {
61  int is_model_year;
62 
63  /* Manufacturer Code */
64  info->manufacturer_code[0] = get_bits (edid[0x08], 2, 6);
65  info->manufacturer_code[1] = get_bits (edid[0x08], 0, 1) << 3;
66  info->manufacturer_code[1] |= get_bits (edid[0x09], 5, 7);
67  info->manufacturer_code[2] = get_bits (edid[0x09], 0, 4);
68  info->manufacturer_code[3] = '\0';
69 
70  info->manufacturer_code[0] += 'A' - 1;
71  info->manufacturer_code[1] += 'A' - 1;
72  info->manufacturer_code[2] += 'A' - 1;
73 
74  /* Product Code */
75  info->product_code = edid[0x0b] << 8 | edid[0x0a];
76 
77  /* Serial Number */
78  info->serial_number =
79  edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | edid[0x0f] << 24;
80 
81  /* Week and Year */
82  is_model_year = FALSE;
83  switch (edid[0x10])
84  {
85  case 0x00:
86  info->production_week = -1;
87  break;
88 
89  case 0xff:
90  info->production_week = -1;
91  is_model_year = TRUE;
92  break;
93 
94  default:
95  info->production_week = edid[0x10];
96  break;
97  }
98 
99  if (is_model_year)
100  {
101  info->production_year = -1;
102  info->model_year = 1990 + edid[0x11];
103  }
104  else
105  {
106  info->production_year = 1990 + edid[0x11];
107  info->model_year = -1;
108  }
109 
110  return TRUE;
111 }
int production_week
Definition: edid.h:87
static int get_bits(int in, int begin, int end)
Definition: edid-parse.c:43
char manufacturer_code[4]
Definition: edid.h:83
int product_code
Definition: edid.h:84
int model_year
Definition: edid.h:89
#define TRUE
Definition: edid-parse.c:33
unsigned int serial_number
Definition: edid.h:85
int production_year
Definition: edid.h:88
#define FALSE
Definition: edid-parse.c:34

◆ dump_monitor_info()

void dump_monitor_info ( MonitorInfo info)

Definition at line 551 of file edid-parse.c.

References MonitorInfo::active_off, DetailedTiming::ad, MonitorInfo::ad, DetailedTiming::analog, MonitorInfo::analog, MonitorInfo::aspect_ratio, MonitorInfo::blue_x, MonitorInfo::blue_y, MonitorInfo::checksum, MonitorInfo::continuous_frequency, MonitorInfo::detailed_timings, DetailedTiming::digital, MonitorInfo::digital, DetailedTiming::digital_sync, DISPLAY_PORT, MonitorInfo::dsc_product_name, MonitorInfo::dsc_serial_number, MonitorInfo::dsc_string, DVI, MonitorInfo::established, FIELD_LEFT, FIELD_RIGHT, FOUR_WAY_INTERLEAVED, Timing::frequency, MonitorInfo::gamma, MonitorInfo::green_x, MonitorInfo::green_y, DetailedTiming::h_addr, DetailedTiming::h_blank, DetailedTiming::h_front_porch, DetailedTiming::h_sync, HDMI_A, HDMI_B, Timing::height, DetailedTiming::height_mm, MonitorInfo::height_mm, i, MonitorInfo::is_digital, MonitorInfo::major_version, MonitorInfo::manufacturer_code, MDDI, MonitorInfo::minor_version, MonitorInfo::model_year, MONOCHROME, MonitorInfo::n_detailed_timings, NO_STEREO, OTHER_COLOR, DetailedTiming::pixel_clock, MonitorInfo::preferred_timing_includes_native, MonitorInfo::product_code, MonitorInfo::production_week, MonitorInfo::production_year, MonitorInfo::red_x, MonitorInfo::red_y, RGB, DetailedTiming::right_border, MonitorInfo::serial_number, SIDE_BY_SIDE, MonitorInfo::srgb_is_standard, MonitorInfo::standard, MonitorInfo::standby, DetailedTiming::stereo, MonitorInfo::suspend, DetailedTiming::top_border, TWO_WAY_LEFT_ON_EVEN, TWO_WAY_RIGHT_ON_EVEN, UNDEFINED, UNDEFINED_COLOR, DetailedTiming::v_addr, DetailedTiming::v_blank, DetailedTiming::v_front_porch, DetailedTiming::v_sync, MonitorInfo::white_x, MonitorInfo::white_y, Timing::width, DetailedTiming::width_mm, MonitorInfo::width_mm, and yesno().

552 {
553  int i;
554 
555  printf ("Checksum: %d (%s)\n",
556  info->checksum, info->checksum? "incorrect" : "correct");
557  printf ("Manufacturer Code: %s\n", info->manufacturer_code);
558  printf ("Product Code: 0x%x\n", info->product_code);
559  printf ("Serial Number: %u\n", info->serial_number);
560 
561  if (info->production_week != -1)
562  printf ("Production Week: %d\n", info->production_week);
563  else
564  printf ("Production Week: unspecified\n");
565 
566  if (info->production_year != -1)
567  printf ("Production Year: %d\n", info->production_year);
568  else
569  printf ("Production Year: unspecified\n");
570 
571  if (info->model_year != -1)
572  printf ("Model Year: %d\n", info->model_year);
573  else
574  printf ("Model Year: unspecified\n");
575 
576  printf ("EDID revision: %d.%d\n", info->major_version, info->minor_version);
577 
578  printf ("Display is %s\n", info->is_digital? "digital" : "analog");
579  if (info->is_digital)
580  {
581  const char *interface;
582  if (info->ad.digital.bits_per_primary != -1)
583  printf ("Bits Per Primary: %d\n", info->ad.digital.bits_per_primary);
584  else
585  printf ("Bits Per Primary: undefined\n");
586 
587  switch (info->ad.digital.interface)
588  {
589  case DVI: interface = "DVI"; break;
590  case HDMI_A: interface = "HDMI-a"; break;
591  case HDMI_B: interface = "HDMI-b"; break;
592  case MDDI: interface = "MDDI"; break;
593  case DISPLAY_PORT: interface = "DisplayPort"; break;
594  case UNDEFINED: interface = "undefined"; break;
595  default: interface = "unknown"; break;
596  }
597  printf ("Interface: %s\n", interface);
598 
599  printf ("RGB 4:4:4: %s\n", yesno (info->ad.digital.rgb444));
600  printf ("YCrCb 4:4:4: %s\n", yesno (info->ad.digital.ycrcb444));
601  printf ("YCrCb 4:2:2: %s\n", yesno (info->ad.digital.ycrcb422));
602  }
603  else
604  {
605  const char *s;
606  printf ("Video Signal Level: %f\n", info->ad.analog.video_signal_level);
607  printf ("Sync Signal Level: %f\n", info->ad.analog.sync_signal_level);
608  printf ("Total Signal Level: %f\n", info->ad.analog.total_signal_level);
609 
610  printf ("Blank to Black: %s\n",
611  yesno (info->ad.analog.blank_to_black));
612  printf ("Separate HV Sync: %s\n",
613  yesno (info->ad.analog.separate_hv_sync));
614  printf ("Composite Sync on H: %s\n",
615  yesno (info->ad.analog.composite_sync_on_h));
616  printf ("Serration on VSync: %s\n",
617  yesno (info->ad.analog.serration_on_vsync));
618 
619  switch (info->ad.analog.color_type)
620  {
621  case UNDEFINED_COLOR: s = "undefined"; break;
622  case MONOCHROME: s = "monochrome"; break;
623  case RGB: s = "rgb"; break;
624  case OTHER_COLOR: s = "other color"; break;
625  default: s = "unknown"; break;
626  };
627 
628  printf ("Color: %s\n", s);
629  }
630 
631  if (info->width_mm == -1)
632  printf ("Width: undefined\n");
633  else
634  printf ("Width: %d mm\n", info->width_mm);
635 
636  if (info->height_mm == -1)
637  printf ("Height: undefined\n");
638  else
639  printf ("Height: %d mm\n", info->height_mm);
640 
641  if (info->aspect_ratio > 0)
642  printf ("Aspect Ratio: %f\n", info->aspect_ratio);
643  else
644  printf ("Aspect Ratio: undefined\n");
645 
646  if (info->gamma >= 0)
647  printf ("Gamma: %f\n", info->gamma);
648  else
649  printf ("Gamma: undefined\n");
650 
651  printf ("Standby: %s\n", yesno (info->standby));
652  printf ("Suspend: %s\n", yesno (info->suspend));
653  printf ("Active Off: %s\n", yesno (info->active_off));
654 
655  printf ("SRGB is Standard: %s\n", yesno (info->srgb_is_standard));
656  printf ("Preferred Timing Includes Native: %s\n",
658  printf ("Continuous Frequency: %s\n", yesno (info->continuous_frequency));
659 
660  printf ("Red X: %f\n", info->red_x);
661  printf ("Red Y: %f\n", info->red_y);
662  printf ("Green X: %f\n", info->green_x);
663  printf ("Green Y: %f\n", info->green_y);
664  printf ("Blue X: %f\n", info->blue_x);
665  printf ("Blue Y: %f\n", info->blue_y);
666  printf ("White X: %f\n", info->white_x);
667  printf ("White Y: %f\n", info->white_y);
668 
669  printf ("Established Timings:\n");
670 
671  for (i = 0; i < 24; ++i)
672  {
673  Timing *timing = &(info->established[i]);
674 
675  if (timing->frequency == 0)
676  break;
677 
678  printf (" %d x %d @ %d Hz\n",
679  timing->width, timing->height, timing->frequency);
680 
681  }
682 
683  printf ("Standard Timings:\n");
684  for (i = 0; i < 8; ++i)
685  {
686  Timing *timing = &(info->standard[i]);
687 
688  if (timing->frequency == 0)
689  break;
690 
691  printf (" %d x %d @ %d Hz\n",
692  timing->width, timing->height, timing->frequency);
693  }
694 
695  for (i = 0; i < info->n_detailed_timings; ++i)
696  {
697  DetailedTiming *timing = &(info->detailed_timings[i]);
698  const char *s;
699 
700  printf ("Timing%s: \n",
701  (i == 0 && info->preferred_timing_includes_native)?
702  " (Preferred)" : "");
703  printf (" Pixel Clock: %d\n", timing->pixel_clock);
704  printf (" H Addressable: %d\n", timing->h_addr);
705  printf (" H Blank: %d\n", timing->h_blank);
706  printf (" H Front Porch: %d\n", timing->h_front_porch);
707  printf (" H Sync: %d\n", timing->h_sync);
708  printf (" V Addressable: %d\n", timing->v_addr);
709  printf (" V Blank: %d\n", timing->v_blank);
710  printf (" V Front Porch: %d\n", timing->v_front_porch);
711  printf (" V Sync: %d\n", timing->v_sync);
712  printf (" Width: %d mm\n", timing->width_mm);
713  printf (" Height: %d mm\n", timing->height_mm);
714  printf (" Right Border: %d\n", timing->right_border);
715  printf (" Top Border: %d\n", timing->top_border);
716  switch (timing->stereo)
717  {
718  default:
719  case NO_STEREO: s = "No Stereo"; break;
720  case FIELD_RIGHT: s = "Field Sequential, Right on Sync"; break;
721  case FIELD_LEFT: s = "Field Sequential, Left on Sync"; break;
722  case TWO_WAY_RIGHT_ON_EVEN: s = "Two-way, Right on Even"; break;
723  case TWO_WAY_LEFT_ON_EVEN: s = "Two-way, Left on Even"; break;
724  case FOUR_WAY_INTERLEAVED: s = "Four-way Interleaved"; break;
725  case SIDE_BY_SIDE: s = "Side-by-Side"; break;
726  }
727  printf (" Stereo: %s\n", s);
728 
729  if (timing->digital_sync)
730  {
731  printf (" Digital Sync:\n");
732  printf (" composite: %s\n", yesno (timing->ad.digital.composite));
733  printf (" serrations: %s\n", yesno (timing->ad.digital.serrations));
734  printf (" negative vsync: %s\n",
735  yesno (timing->ad.digital.negative_vsync));
736  printf (" negative hsync: %s\n",
737  yesno (timing->ad.digital.negative_hsync));
738  }
739  else
740  {
741  printf (" Analog Sync:\n");
742  printf (" bipolar: %s\n", yesno (timing->ad.analog.bipolar));
743  printf (" serrations: %s\n", yesno (timing->ad.analog.serrations));
744  printf (" sync on green: %s\n", yesno (
745  timing->ad.analog.sync_on_green));
746  }
747  }
748 
749  printf ("Detailed Product information:\n");
750  printf (" Product Name: %s\n", info->dsc_product_name);
751  printf (" Serial Number: %s\n", info->dsc_serial_number);
752  printf (" Unspecified String: %s\n", info->dsc_string);
753 }
double green_y
Definition: edid.h:140
char dsc_product_name[14]
Definition: edid.h:160
int n_detailed_timings
Definition: edid.h:149
int production_week
Definition: edid.h:87
Definition: edid.h:20
int h_sync
Definition: edid.h:47
int h_front_porch
Definition: edid.h:48
int frequency
Definition: edid.h:39
int height
Definition: edid.h:38
int minor_version
Definition: edid.h:92
GLdouble s
Definition: SDL_opengl.h:2063
Definition: edid.h:8
char manufacturer_code[4]
Definition: edid.h:83
int active_off
Definition: edid.h:131
int suspend
Definition: edid.h:130
int standby
Definition: edid.h:129
int major_version
Definition: edid.h:91
int height_mm
Definition: edid.h:54
int product_code
Definition: edid.h:84
double white_y
Definition: edid.h:144
int width
Definition: edid.h:37
int checksum
Definition: edid.h:82
Definition: edid.h:10
double red_x
Definition: edid.h:137
struct MonitorInfo::@47::@49 analog
char dsc_string[14]
Definition: edid.h:161
int width_mm
Definition: edid.h:123
int pixel_clock
Definition: edid.h:44
double blue_x
Definition: edid.h:141
struct DetailedTiming::@44::@45 analog
Definition: edid.h:35
int model_year
Definition: edid.h:89
Timing standard[8]
Definition: edid.h:147
int digital_sync
Definition: edid.h:60
int top_border
Definition: edid.h:56
int right_border
Definition: edid.h:55
Definition: edid.h:11
struct DetailedTiming::@44::@46 digital
static const char * yesno(int v)
Definition: edid-parse.c:545
int v_front_porch
Definition: edid.h:52
Definition: edid.h:12
int continuous_frequency
Definition: edid.h:135
double aspect_ratio
Definition: edid.h:125
int v_addr
Definition: edid.h:49
int preferred_timing_includes_native
Definition: edid.h:134
Timing established[24]
Definition: edid.h:146
int srgb_is_standard
Definition: edid.h:133
int h_addr
Definition: edid.h:45
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
int v_sync
Definition: edid.h:51
int is_digital
Definition: edid.h:94
union DetailedTiming::@44 ad
DetailedTiming detailed_timings[4]
Definition: edid.h:150
StereoType stereo
Definition: edid.h:58
int width_mm
Definition: edid.h:53
char dsc_serial_number[14]
Definition: edid.h:159
int height_mm
Definition: edid.h:124
int v_blank
Definition: edid.h:50
Definition: edid.h:9
Definition: edid.h:26
double white_x
Definition: edid.h:143
unsigned int serial_number
Definition: edid.h:85
int production_year
Definition: edid.h:88
GLboolean GLboolean GLboolean GLboolean a
double gamma
Definition: edid.h:127
GLboolean GLboolean GLboolean b
double green_x
Definition: edid.h:139
int h_blank
Definition: edid.h:46
double blue_y
Definition: edid.h:142
struct MonitorInfo::@47::@48 digital
double red_y
Definition: edid.h:138
union MonitorInfo::@47 ad

◆ get_bit()

static int get_bit ( int  in,
int  bit 
)
static

Definition at line 37 of file edid-parse.c.

Referenced by decode_detailed_timing(), decode_display_parameters(), decode_established_timings(), and decode_fraction().

38 {
39  return (in & (1 << bit)) >> bit;
40 }
GLuint in

◆ get_bits()

static int get_bits ( int  in,
int  begin,
int  end 
)
static

Definition at line 43 of file edid-parse.c.

Referenced by decode_color_characteristics(), decode_detailed_timing(), decode_display_parameters(), decode_standard_timings(), and decode_vendor_and_product_identification().

44 {
45  int mask = (1 << (end - begin + 1)) - 1;
46 
47  return (in >> begin) & mask;
48 }
GLuint GLuint end
Definition: SDL_opengl.h:1571
GLenum GLint GLuint mask
GLuint in

◆ yesno()

static const char* yesno ( int  v)
static

Definition at line 545 of file edid-parse.c.

Referenced by dump_monitor_info().

546 {
547  return v? "yes" : "no";
548 }
const GLdouble * v
Definition: SDL_opengl.h:2064