through the unified interface find ranges section, max time clock and 
horizon & vertical size respectively.

---
 hw/xfree86/ddc/interpret_edid.c |  120 +++++++++++++++++++++++----------------
 1 files changed, 72 insertions(+), 48 deletions(-)

diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index f04c6bc..d2a9fb4 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -54,11 +54,25 @@ static void get_detailed_timing_section(Uchar*, struct      
detailed_timings *);
 static Bool validate_version(int scrnIndex, struct edid_version *);
 
 static void
+find_ranges_section(struct detailed_monitor_section *det, void *ranges)
+{
+   if (det->type == DS_RANGES && det->section.ranges.max_clock)
+       *(struct monitor_ranges **)ranges = &det->section.ranges;
+}
+
+static void
+find_max_detailed_clock(struct detailed_monitor_section *det, void *ret)
+{
+    if (det->type == DT) {
+        *(int *)ret = max(*((int *)ret),
+                          det->section.d_timings.clock);
+    }
+}
+
+static void
 handle_edid_quirks(xf86MonPtr m)
 {
-    int i, j;
-    struct detailed_timings *preferred_timing;
-    struct monitor_ranges *ranges;
+    struct monitor_ranges *ranges = NULL;
 
     /*
      * max_clock is only encoded in EDID in tens of MHz, so occasionally we
@@ -66,28 +80,49 @@ handle_edid_quirks(xf86MonPtr m)
      * similar.  Strictly we should refuse to round up too far, but let's
      * see how well this works.
      */
-    for (i = 0; i < 4; i++) {
-       if (m->det_mon[i].type == DS_RANGES) {
-           ranges = &m->det_mon[i].section.ranges;
-           for (j = 0; j < 4; j++) {
-               if (m->det_mon[j].type == DT) {
-                   preferred_timing = &m->det_mon[j].section.d_timings;
-                   if (!ranges->max_clock) continue; /* zero is legal */
-                   if (ranges->max_clock * 1000000 < preferred_timing->clock) {
-                       xf86Msg(X_WARNING,
-                           "EDID preferred timing clock %.2fMHz exceeds "
-                           "claimed max %dMHz, fixing\n",
-                           preferred_timing->clock / 1.0e6,
-                           ranges->max_clock);
-                       ranges->max_clock =
-                           (preferred_timing->clock+999999)/1000000;
-                       return;
-                   }
-               }
-           }
-       }
+
+    /* Try to find Monitor Range and max clock, then re-set range value*/
+    xf86ForEachDetailedBlock(m, find_ranges_section, &ranges);
+    if (ranges && ranges->max_clock) {
+        int clock = 0;
+        xf86ForEachDetailedBlock(m, find_max_detailed_clock, &clock);
+        if (clock && (ranges->max_clock * 1e6 < clock)) {
+            xf86Msg(X_WARNING, "EDID timing clock %.2f exceeds claimed max "
+                    "%dMHz, fixing\n", clock / 1.0e6, ranges->max_clock);
+            ranges->max_clock = (clock+999999)/1e6;
+        }
+    }
+}
+
+struct det_hv_parameter {
+    int real_hsize;
+    int real_vsize;
+    float target_aspect;
+};
+
+static void handle_detailed_hvsize(struct detailed_monitor_section *det_mon,
+                                   void *data)
+{
+    struct det_hv_parameter *p = (struct det_hv_parameter *)data;
+    float timing_aspect;
+
+    if (det_mon->type == DT) {
+        struct detailed_timings *timing;
+        timing = &det_mon->section.d_timings;
+
+        if (!timing->v_size)
+            return;
+
+        timing_aspect = (float)timing->h_size / timing->v_size;
+        if (fabs(1 - (timing_aspect / p->target_aspect)) < 0.05) {
+            p->real_hsize = max(p->real_hsize, timing->h_size);
+            p->real_vsize = max(p->real_vsize, timing->v_size);
+        }
     }
+}
 
+static void encode_aspect_ratio(xf86MonPtr m)
+{
     /*
      * some monitors encode the aspect ratio instead of the physical size.
      * try to find the largest detailed timing that matches that aspect
@@ -97,38 +132,26 @@ handle_edid_quirks(xf86MonPtr m)
        (m->features.hsize == 16 && m->features.vsize == 10) ||
        (m->features.hsize == 4 && m->features.vsize == 3) ||
        (m->features.hsize == 5 && m->features.vsize == 4)) {
-       int real_hsize = 0, real_vsize = 0;
-       float target_aspect, timing_aspect;
-       
-       target_aspect = (float)m->features.hsize / (float)m->features.vsize;
-       for (i = 0; i < 4; i++) {
-           if (m->det_mon[i].type == DT) {
-               struct detailed_timings *timing;
-               timing = &m->det_mon[i].section.d_timings;
-
-               if (!timing->v_size)
-                   continue;
-
-               timing_aspect = (float)timing->h_size / (float)timing->v_size;
-               if (fabs(1 - (timing_aspect / target_aspect)) < 0.05) {
-                   real_hsize = max(real_hsize, timing->h_size);
-                   real_vsize = max(real_vsize, timing->v_size);
-               }
-           }
-       }
 
-       if (!real_hsize || !real_vsize) {
+        struct det_hv_parameter p;
+        p.real_hsize = 0;
+        p.real_vsize = 0;
+        p.target_aspect = (float)m->features.hsize /m->features.vsize;
+
+        xf86ForEachDetailedBlock(m, handle_detailed_hvsize, &p);
+
+       if (!p.real_hsize || !p.real_vsize) {
            m->features.hsize = m->features.vsize = 0;
-       } else if ((m->features.hsize * 10 == real_hsize) &&
-                  (m->features.vsize * 10 == real_vsize)) {
+       } else if ((m->features.hsize * 10 == p.real_hsize) &&
+                  (m->features.vsize * 10 == p.real_vsize)) {
            /* exact match is just unlikely, should do a better check though */
            m->features.hsize = m->features.vsize = 0;
        } else {
            /* convert mm to cm */
-           m->features.hsize = (real_hsize + 5) / 10;
-           m->features.vsize = (real_vsize + 5) / 10;
+           m->features.hsize = (p.real_hsize + 5) / 10;
+           m->features.vsize = (p.real_vsize + 5) / 10;
        }
-       
+
        xf86Msg(X_INFO, "Quirked EDID physical size to %dx%d cm\n",
                m->features.hsize, m->features.vsize);
     }
@@ -157,6 +180,7 @@ xf86InterpretEDID(int scrnIndex, Uchar *block)
     m->no_sections = (int)*(char *)SECTION(NO_EDID,block);
 
     handle_edid_quirks(m);
+    encode_aspect_ratio(m);
 
     return (m);
 
-- 
1.5.4.4



_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to