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

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

◆ TRUE

#define TRUE   1

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

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.

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 }

References MonitorInfo::checksum, and i.

Referenced by decode_edid().

◆ decode_color_characteristics()

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

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

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 }

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().

◆ decode_descriptors()

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

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

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 }

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

Referenced by decode_edid().

◆ decode_detailed_timing()

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

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

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 }

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().

◆ decode_display_descriptor()

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

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

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 }

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

Referenced by decode_descriptors().

◆ decode_display_parameters()

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

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

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 }

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().

◆ decode_edid()

MonitorInfo* decode_edid ( const uchar edid)

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

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 }

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.

◆ decode_edid_version()

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

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

115 {
116  info->major_version = edid[0x12];
117  info->minor_version = edid[0x13];
118 
119  return TRUE;
120 }

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

Referenced by decode_edid().

◆ decode_established_timings()

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

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

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 }

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

Referenced by decode_edid().

◆ decode_fraction()

static double decode_fraction ( int  high,
int  low 
)
static

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

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 }

References get_bit(), i, and SDL_pow.

Referenced by decode_color_characteristics().

◆ decode_header()

static int decode_header ( const uchar edid)
static

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

52 {
53  if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0)
54  return TRUE;
55  return FALSE;
56 }

References FALSE, and TRUE.

Referenced by decode_edid().

◆ 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.

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 }

References i.

Referenced by decode_display_descriptor().

◆ decode_standard_timings()

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

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

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 }

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

Referenced by decode_edid().

◆ 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.

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 }

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().

◆ dump_monitor_info()

void dump_monitor_info ( MonitorInfo info)

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

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 }

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().

◆ get_bit()

static int get_bit ( int  in,
int  bit 
)
static

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

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

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

◆ get_bits()

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

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

44 {
45  int mask = (1 << (end - begin + 1)) - 1;
46 
47  return (in >> begin) & mask;
48 }

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

◆ yesno()

static const char* yesno ( int  v)
static

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

546 {
547  return v? "yes" : "no";
548 }

Referenced by dump_monitor_info().

uchar
unsigned char uchar
Definition: edid.h:1
MonitorInfo::preferred_timing_includes_native
int preferred_timing_includes_native
Definition: edid.h:134
MonitorInfo::dsc_string
char dsc_string[14]
Definition: edid.h:161
OTHER_COLOR
@ OTHER_COLOR
Definition: edid.h:21
mask
GLenum GLint GLuint mask
Definition: SDL_opengl_glext.h:660
DetailedTiming::h_sync
int h_sync
Definition: edid.h:47
DetailedTiming::interlaced
int interlaced
Definition: edid.h:57
decode_descriptors
static int decode_descriptors(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:482
in
GLuint in
Definition: SDL_opengl_glext.h:7943
FOUR_WAY_INTERLEAVED
@ FOUR_WAY_INTERLEAVED
Definition: edid.h:31
end
GLuint GLuint end
Definition: SDL_opengl.h:1571
decode_detailed_timing
static void decode_detailed_timing(const uchar *timing, DetailedTiming *detailed)
Definition: edid-parse.c:419
NULL
#define NULL
Definition: begin_code.h:167
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1112
MonitorInfo::standard
Timing standard[8]
Definition: edid.h:147
TRUE
#define TRUE
Definition: edid-parse.c:33
MonitorInfo::ad
union MonitorInfo::@270 ad
MonitorInfo
Definition: edid.h:80
HDMI_B
@ HDMI_B
Definition: edid.h:11
DetailedTiming::height_mm
int height_mm
Definition: edid.h:54
MonitorInfo::established
Timing established[24]
Definition: edid.h:146
decode_display_descriptor
static void decode_display_descriptor(const uchar *desc, MonitorInfo *info)
Definition: edid-parse.c:381
DetailedTiming::top_border
int top_border
Definition: edid.h:56
UNDEFINED
@ UNDEFINED
Definition: edid.h:8
TWO_WAY_LEFT_ON_EVEN
@ TWO_WAY_LEFT_ON_EVEN
Definition: edid.h:30
MonitorInfo::manufacturer_code
char manufacturer_code[4]
Definition: edid.h:83
decode_edid_version
static int decode_edid_version(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:114
MDDI
@ MDDI
Definition: edid.h:12
StereoType
StereoType
Definition: edid.h:24
decode_lf_string
static void decode_lf_string(const uchar *s, int n_chars, char *result)
Definition: edid-parse.c:358
RGB
@ RGB
Definition: edid.h:20
decode_established_timings
static int decode_established_timings(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:273
index
GLuint index
Definition: SDL_opengl_glext.h:663
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1112
v
const GLdouble * v
Definition: SDL_opengl.h:2064
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1949
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
MONOCHROME
@ MONOCHROME
Definition: edid.h:19
HDMI_A
@ HDMI_A
Definition: edid.h:10
decode_display_parameters
static int decode_display_parameters(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:123
Timing::frequency
int frequency
Definition: edid.h:39
MonitorInfo::aspect_ratio
double aspect_ratio
Definition: edid.h:125
MonitorInfo::analog
struct MonitorInfo::@270::@272 analog
TWO_WAY_RIGHT_ON_EVEN
@ TWO_WAY_RIGHT_ON_EVEN
Definition: edid.h:29
Timing::height
int height
Definition: edid.h:38
DetailedTiming::analog
struct DetailedTiming::@267::@268 analog
MonitorInfo::blue_x
double blue_x
Definition: edid.h:141
MonitorInfo::active_off
int active_off
Definition: edid.h:131
MonitorInfo::suspend
int suspend
Definition: edid.h:130
DetailedTiming::pixel_clock
int pixel_clock
Definition: edid.h:44
MonitorInfo::green_x
double green_x
Definition: edid.h:139
DetailedTiming::h_addr
int h_addr
Definition: edid.h:45
decode_color_characteristics
static int decode_color_characteristics(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:258
MonitorInfo::blue_y
double blue_y
Definition: edid.h:142
DetailedTiming::right_border
int right_border
Definition: edid.h:55
MonitorInfo::dsc_serial_number
char dsc_serial_number[14]
Definition: edid.h:159
MonitorInfo::n_detailed_timings
int n_detailed_timings
Definition: edid.h:149
MonitorInfo::width_mm
int width_mm
Definition: edid.h:123
DetailedTiming::digital
struct DetailedTiming::@267::@269 digital
MonitorInfo::minor_version
int minor_version
Definition: edid.h:92
MonitorInfo::height_mm
int height_mm
Definition: edid.h:124
get_bit
static int get_bit(int in, int bit)
Definition: edid-parse.c:37
DetailedTiming::v_front_porch
int v_front_porch
Definition: edid.h:52
SDL_pow
#define SDL_pow
Definition: SDL_dynapi_overrides.h:433
ColorType
ColorType
Definition: edid.h:16
DetailedTiming::digital_sync
int digital_sync
Definition: edid.h:60
MonitorInfo::production_week
int production_week
Definition: edid.h:87
NO_STEREO
@ NO_STEREO
Definition: edid.h:26
decode_fraction
static double decode_fraction(int high, int low)
Definition: edid-parse.c:244
decode_header
static int decode_header(const uchar *edid)
Definition: edid-parse.c:51
MonitorInfo::is_digital
int is_digital
Definition: edid.h:94
DetailedTiming::v_sync
int v_sync
Definition: edid.h:51
levels
GLsizei levels
Definition: SDL_opengl_glext.h:2167
MonitorInfo::serial_number
unsigned int serial_number
Definition: edid.h:85
DetailedTiming::v_addr
int v_addr
Definition: edid.h:49
Timing
Definition: edid.h:35
MonitorInfo::green_y
double green_y
Definition: edid.h:140
yesno
static const char * yesno(int v)
Definition: edid-parse.c:545
Timing::width
int width
Definition: edid.h:37
first
const GLint * first
Definition: SDL_opengl_glext.h:371
DetailedTiming::v_blank
int v_blank
Definition: edid.h:50
MonitorInfo::standby
int standby
Definition: edid.h:129
UNDEFINED_COLOR
@ UNDEFINED_COLOR
Definition: edid.h:18
FIELD_RIGHT
@ FIELD_RIGHT
Definition: edid.h:27
MonitorInfo::srgb_is_standard
int srgb_is_standard
Definition: edid.h:133
DetailedTiming::stereo
StereoType stereo
Definition: edid.h:58
DetailedTiming::width_mm
int width_mm
Definition: edid.h:53
s
GLdouble s
Definition: SDL_opengl.h:2063
MonitorInfo::detailed_timings
DetailedTiming detailed_timings[4]
Definition: edid.h:150
Interface
Interface
Definition: edid.h:6
SIDE_BY_SIDE
@ SIDE_BY_SIDE
Definition: edid.h:32
FIELD_LEFT
@ FIELD_LEFT
Definition: edid.h:28
decode_check_sum
static void decode_check_sum(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:510
MonitorInfo::red_y
double red_y
Definition: edid.h:138
DISPLAY_PORT
@ DISPLAY_PORT
Definition: edid.h:13
MonitorInfo::gamma
double gamma
Definition: edid.h:127
MonitorInfo::white_y
double white_y
Definition: edid.h:144
MonitorInfo::digital
struct MonitorInfo::@270::@271 digital
bits
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition: SDL_opengl_glext.h:6179
decode_vendor_and_product_identification
static int decode_vendor_and_product_identification(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:59
j
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
DetailedTiming::h_blank
int h_blank
Definition: edid.h:46
DetailedTiming::h_front_porch
int h_front_porch
Definition: edid.h:48
MonitorInfo::dsc_product_name
char dsc_product_name[14]
Definition: edid.h:160
decode_standard_timings
static int decode_standard_timings(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:326
MonitorInfo::model_year
int model_year
Definition: edid.h:89
MonitorInfo::white_x
double white_x
Definition: edid.h:143
MonitorInfo::product_code
int product_code
Definition: edid.h:84
free
SDL_EventEntry * free
Definition: SDL_events.c:89
get_bits
static int get_bits(int in, int begin, int end)
Definition: edid-parse.c:43
DetailedTiming::ad
union DetailedTiming::@267 ad
idx
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
Definition: pixman-arm-neon-asm.h:100
MonitorInfo::checksum
int checksum
Definition: edid.h:82
i
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
MonitorInfo::major_version
int major_version
Definition: edid.h:91
MonitorInfo::production_year
int production_year
Definition: edid.h:88
MonitorInfo::continuous_frequency
int continuous_frequency
Definition: edid.h:135
FALSE
#define FALSE
Definition: edid-parse.c:34
DVI
@ DVI
Definition: edid.h:9
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:734
MonitorInfo::red_x
double red_x
Definition: edid.h:137
DetailedTiming
Definition: edid.h:42