handle detailed timing operation,e.g. set up Monitor from detailed timing 
block 
from EDID and cea ext

---
 hw/xfree86/modes/xf86Crtc.c |  125 ++++++++++++++++++++++++++++---------------
 1 files changed, 82 insertions(+), 43 deletions(-)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 309eb99..3eb7cb6 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1530,6 +1530,40 @@ GuessRangeFromModes(MonPtr mon, DisplayModePtr mode)
        mon->vrefresh[0].lo = 58.0;
 }
 
+struct det_monrec_parameter {
+    MonRec *mon_rec;
+    int *max_clock;
+    int *sync_source; 
+};
+
+static void handle_detailed_monrec(struct detailed_monitor_section *det_mon,
+                                   void *data)
+{      
+    enum { sync_config, sync_edid, sync_default };
+    struct det_monrec_parameter *p; 
+    p = (struct det_monrec_parameter *)data;
+
+    if (det_mon->type == DS_RANGES) {
+       struct monitor_ranges   *ranges = &det_mon->section.ranges;
+        if (p->mon_rec->nHsync == 0 && ranges->max_h) {
+            p->mon_rec->hsync[p->mon_rec->nHsync].lo = ranges->min_h;
+            p->mon_rec->hsync[p->mon_rec->nHsync].hi = ranges->max_h;
+            p->mon_rec->nHsync++;
+            if (*p->sync_source == sync_default)
+                *p->sync_source = sync_edid;
+        }
+        if (p->mon_rec->nVrefresh == 0 && ranges->max_v) {
+            p->mon_rec->vrefresh[p->mon_rec->nVrefresh].lo = ranges->min_v;
+            p->mon_rec->vrefresh[p->mon_rec->nVrefresh].hi = ranges->max_v;
+            p->mon_rec->nVrefresh++;
+            if (*p->sync_source == sync_default)
+                *p->sync_source = sync_edid;
+        }
+        if (ranges->max_clock * 1000 > *p->max_clock)
+            *p->max_clock = ranges->max_clock * 1000;
+    }
+}
+
 void
 xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 {
@@ -1610,40 +1644,20 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int 
maxY)
        
        if (edid_monitor)
        {
-           int                     i;
-           Bool                    set_hsync = mon_rec.nHsync == 0;
-           Bool                    set_vrefresh = mon_rec.nVrefresh == 0;
-           struct disp_features    *features = &edid_monitor->features;
+            struct det_monrec_parameter p;
+            struct disp_features    *features = &edid_monitor->features;
 
            /* if display is not continuous-frequency, don't add default modes 
*/
            if (!GTF_SUPPORTED(features->msc))
                add_default_modes = FALSE;
-
-           for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof 
(edid_monitor->det_mon[0]); i++)
-           {
-               if (edid_monitor->det_mon[i].type == DS_RANGES)
-               {
-                   struct monitor_ranges   *ranges = 
&edid_monitor->det_mon[i].section.ranges;
-                   if (set_hsync && ranges->max_h)
-                   {
-                       mon_rec.hsync[mon_rec.nHsync].lo = ranges->min_h;
-                       mon_rec.hsync[mon_rec.nHsync].hi = ranges->max_h;
-                       mon_rec.nHsync++;
-                       if (sync_source == sync_default)
-                           sync_source = sync_edid;
-                   }
-                   if (set_vrefresh && ranges->max_v)
-                   {
-                       mon_rec.vrefresh[mon_rec.nVrefresh].lo = ranges->min_v;
-                       mon_rec.vrefresh[mon_rec.nVrefresh].hi = ranges->max_v;
-                       mon_rec.nVrefresh++;
-                       if (sync_source == sync_default)
-                           sync_source = sync_edid;
-                   }
-                   if (ranges->max_clock * 1000 > max_clock)
-                       max_clock = ranges->max_clock * 1000;
-               }
-           }
+            
+            p.mon_rec = &mon_rec;
+            p.max_clock = &max_clock;
+            p.sync_source = (int *)&sync_source;
+
+            xf86ForEachDetailedBlock(edid_monitor,
+                                    handle_detailed_monrec,
+                                    &p);
        }
 
        if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
@@ -2888,6 +2902,36 @@ xf86OutputSetEDIDProperty (xf86OutputPtr output, void 
*data, int data_len)
 
 #endif
 
+/* Pull out a phyiscal size from a detailed timing if available. */
+struct det_phySize_parameter {
+    xf86OutputPtr output;
+    ddc_quirk_t quirks;
+    Bool ret;   
+};
+
+void static handle_detailed_physical_size(struct detailed_monitor_section 
+                                         *det_mon, void *data)
+{
+    struct det_phySize_parameter *p;
+    p = (struct det_phySize_parameter *)data;
+
+    if (p->ret == TRUE )
+        return ;
+
+    xf86DetTimingApplyQuirks(det_mon, p->quirks,
+                             p->output->MonInfo->features.hsize,
+                             p->output->MonInfo->features.vsize);
+        
+    if (det_mon->type == DT &&
+        det_mon->section.d_timings.h_size != 0 &&
+        det_mon->section.d_timings.v_size != 0) {
+
+        p->output->mm_width = det_mon->section.d_timings.h_size;
+        p->output->mm_height = det_mon->section.d_timings.v_size;
+        p->ret = TRUE;
+    }
+}
+
 /**
  * Set the EDID information for the specified output
  */
@@ -2931,19 +2975,14 @@ xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr 
edid_mon)
     xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, 
size);
 #endif
 
-    if (edid_mon)
-    {
-       /* Pull out a phyiscal size from a detailed timing if available. */
-       for (i = 0; i < 4; i++) {
-           if (edid_mon->det_mon[i].type == DT &&
-               edid_mon->det_mon[i].section.d_timings.h_size != 0 &&
-               edid_mon->det_mon[i].section.d_timings.v_size != 0)
-           {
-               output->mm_width = 
edid_mon->det_mon[i].section.d_timings.h_size;
-               output->mm_height = 
edid_mon->det_mon[i].section.d_timings.v_size;
-               break;
-           }
-       }
+    if (edid_mon) {
+
+        struct det_phySize_parameter p;
+        p.output = output;
+        p.quirks = xf86DDCDetectQuirks(scrn->scrnIndex,edid_mon, FALSE);
+        p.ret = FALSE;
+        xf86ForEachDetailedBlock(edid_mon, 
+                                 handle_detailed_physical_size, &p);
     
        /* if no mm size is available from a detailed timing, check the max 
size field */
        if ((!output->mm_width || !output->mm_height) &&
-- 
1.5.4.4



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

Reply via email to