SDL  2.0
edid-parse.c
Go to the documentation of this file.
1 /*
2  * Copyright 2007 Red Hat, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 /* Author: Soren Sandmann <sandmann@redhat.com> */
24 #include "../../SDL_internal.h"
25 #include "SDL_stdinc.h"
26 
27 #include "edid.h"
28 #include <stdlib.h>
29 #include <string.h>
30 #include <math.h>
31 #include <stdio.h>
32 
33 #define TRUE 1
34 #define FALSE 0
35 
36 static int
37 get_bit (int in, int bit)
38 {
39  return (in & (1 << bit)) >> bit;
40 }
41 
42 static int
43 get_bits (int in, int begin, int end)
44 {
45  int mask = (1 << (end - begin + 1)) - 1;
46 
47  return (in >> begin) & mask;
48 }
49 
50 static int
51 decode_header (const uchar *edid)
52 {
53  if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0)
54  return TRUE;
55  return FALSE;
56 }
57 
58 static int
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 }
112 
113 static int
115 {
116  info->major_version = edid[0x12];
117  info->minor_version = edid[0x13];
118 
119  return TRUE;
120 }
121 
122 static int
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 }
242 
243 static double
244 decode_fraction (int high, int low)
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 }
256 
257 static int
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 }
271 
272 static int
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 }
324 
325 static int
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 }
356 
357 static void
358 decode_lf_string (const uchar *s, int n_chars, char *result)
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 }
379 
380 static void
382  MonitorInfo *info)
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 }
417 
418 static void
420  DetailedTiming *detailed)
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 }
480 
481 static int
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 }
508 
509 static void
510 decode_check_sum (const uchar *edid,
511  MonitorInfo *info)
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 }
521 
522 MonitorInfo *
523 decode_edid (const uchar *edid)
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 }
543 
544 static const char *
545 yesno (int v)
546 {
547  return v? "yes" : "no";
548 }
549 
550 void
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 }
754 
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:81
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
MDDI
@ MDDI
Definition: edid.h:12
decode_edid_version
static int decode_edid_version(const uchar *edid, MonitorInfo *info)
Definition: edid-parse.c:114
StereoType
StereoType
Definition: edid.h:25
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:17
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:36
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
edid.h
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
dump_monitor_info
void dump_monitor_info(MonitorInfo *info)
Definition: edid-parse.c:551
decode_edid
MonitorInfo * decode_edid(const uchar *edid)
Definition: edid-parse.c:523
DetailedTiming::width_mm
int width_mm
Definition: edid.h:53
s
GLdouble s
Definition: SDL_opengl.h:2063
SDL_stdinc.h
MonitorInfo::detailed_timings
DetailedTiming detailed_timings[4]
Definition: edid.h:150
Interface
Interface
Definition: edid.h:7
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:43