[PATCH 2/9] detailed timing unified interface

Ma Ling ling.ma at intel.com
Fri Feb 27 00:31:27 PST 2009


construct unified interface, anytime when program need to handle detailed timing block,
it always dynamically parse and deal with it through the interface.

---
 hw/xfree86/ddc/interpret_edid.c |  182 +++++++++++++++++++++++++++------------
 hw/xfree86/ddc/xf86DDC.h        |    5 +
 2 files changed, 132 insertions(+), 55 deletions(-)

diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index c0e3df9..f04c6bc 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -41,6 +41,8 @@ static void get_display_section(Uchar*, struct disp_features *,
 static void get_established_timing_section(Uchar*, struct established_timings *);
 static void get_std_timing_section(Uchar*, struct std_timings *,
 				   struct edid_version *);
+static void fetch_detailed_block(Uchar *c, struct edid_version *ver,
+                                 struct detailed_monitor_section *det_mon);
 static void get_dt_md_section(Uchar *, struct edid_version *,
 			      struct detailed_monitor_section *det_mon);
 static void copy_string(Uchar *, Uchar *);
@@ -163,6 +165,70 @@ xf86InterpretEDID(int scrnIndex, Uchar *block)
     return NULL;
 }
 
+static int get_cea_detail_timing(Uchar *blk, xf86MonPtr mon,
+                                 struct detailed_monitor_section *det_mon)
+{
+    int dt_num;
+    int dt_offset = ((struct cea_ext_body *)blk)->dt_offset;
+
+    dt_num = 0;
+
+    if (dt_offset < CEA_EXT_MIN_DATA_OFFSET)
+        return dt_num;
+
+    for (; dt_offset < (CEA_EXT_MAX_DATA_OFFSET - DET_TIMING_INFO_LEN) &&
+           dt_num < CEA_EXT_DET_TIMING_NUM;
+	   _NEXT_DT_MD_SECTION(dt_offset)) {
+
+        fetch_detailed_block(blk + dt_offset, &mon->ver, det_mon + dt_num);
+        dt_num = dt_num + 1 ;
+    }
+
+    return dt_num;
+}
+
+static void handle_cea_detail_block(Uchar *ext, xf86MonPtr mon,
+                                    handle_detailed_fn fn,
+                                    void *data)
+{
+    int i;
+    struct detailed_monitor_section det_mon[CEA_EXT_DET_TIMING_NUM];
+    int det_mon_num;
+
+    det_mon_num = get_cea_detail_timing(ext, mon, det_mon);
+
+    for (i = 0; i < det_mon_num; i++)
+        fn(det_mon + i, data);
+}
+
+void xf86ForEachDetailedBlock(xf86MonPtr mon,
+                              handle_detailed_fn fn,
+                              void *data)
+{
+    int i;
+    Uchar *ext;
+
+    if (mon == NULL)
+        return;
+
+    for (i = 0; i < DET_TIMINGS; i++)
+        fn(mon->det_mon + i, data);
+
+    for (i = 0; i < mon->no_sections; i++) {
+        ext = mon->rawData + EDID1_LEN * (i + 1);
+        switch (ext[EXT_TAG]){
+        case CEA_EXT:
+            handle_cea_detail_block(ext, mon, fn, data);
+            break;
+        case VTB_EXT:
+        case DI_EXT:
+        case LS_EXT:
+        case MI_EXT:
+	    break;
+        }
+    }
+}
+
 xf86MonPtr
 xf86InterpretEEDID(int scrnIndex, Uchar *block)
 {
@@ -285,65 +351,71 @@ get_std_timing_section(Uchar *c, struct std_timings *r,
 }
 
 static void
-get_dt_md_section(Uchar *c, struct edid_version *ver, 
-		  struct detailed_monitor_section *det_mon)
+fetch_detailed_block(Uchar *c, struct edid_version *ver,
+                     struct detailed_monitor_section *det_mon)
 {
-  int i;
- 
-  for (i=0;i<DET_TIMINGS;i++) {  
     if (ver->version == 1 && ver->revision >= 1 && IS_MONITOR_DESC) {
+        switch (MONITOR_DESC_TYPE) {
+        case SERIAL_NUMBER:
+            det_mon->type = DS_SERIAL;
+            copy_string(c,det_mon->section.serial);
+            break;
+        case ASCII_STR:
+            det_mon->type = DS_ASCII_STR;
+            copy_string(c,det_mon->section.ascii_data);
+            break;
+        case MONITOR_RANGES:
+            det_mon->type = DS_RANGES;
+            get_monitor_ranges(c,&det_mon->section.ranges);
+            break;
+        case MONITOR_NAME:
+            det_mon->type = DS_NAME;
+            copy_string(c,det_mon->section.name);
+            break;
+        case ADD_COLOR_POINT:
+            det_mon->type = DS_WHITE_P;
+            get_whitepoint_section(c,det_mon->section.wp);
+            break;
+        case ADD_STD_TIMINGS:
+            det_mon->type = DS_STD_TIMINGS;
+            get_dst_timing_section(c,det_mon->section.std_t, ver);
+            break;
+        case COLOR_MANAGEMENT_DATA:
+            det_mon->type = DS_CMD;
+            break;
+        case CVT_3BYTE_DATA:
+            det_mon->type = DS_CVT;
+            get_cvt_timing_section(c, det_mon->section.cvt);
+            break;
+        case ADD_EST_TIMINGS:
+            det_mon->type = DS_EST_III;
+            break;
+        case ADD_DUMMY:
+            det_mon->type = DS_DUMMY;
+            break;
+        default:
+            det_mon->type = DS_UNKOWN;
+            break;
+        }
+        if (c[3] <= 0x0F) {
+            det_mon->type = DS_VENDOR + c[3];
+        }
+    } else {
+        det_mon->type = DT;
+        get_detailed_timing_section(c, &det_mon->section.d_timings);
+    }
+}
+
+static void
+get_dt_md_section(Uchar *c, struct edid_version *ver,
+		  struct detailed_monitor_section *det_mon)
+{
+    int i;
 
-      switch (MONITOR_DESC_TYPE) {
-      case SERIAL_NUMBER:
-	det_mon[i].type = DS_SERIAL;
-	copy_string(c,det_mon[i].section.serial);
-	break;
-      case ASCII_STR:
-	det_mon[i].type = DS_ASCII_STR;
-	copy_string(c,det_mon[i].section.ascii_data);
-	break;
-      case MONITOR_RANGES:
-	det_mon[i].type = DS_RANGES;
-	get_monitor_ranges(c,&det_mon[i].section.ranges);
-	break;
-      case MONITOR_NAME:
-	det_mon[i].type = DS_NAME;
-	copy_string(c,det_mon[i].section.name);
-	break;
-      case ADD_COLOR_POINT:
-	det_mon[i].type = DS_WHITE_P;
-	get_whitepoint_section(c,det_mon[i].section.wp);
-	break;
-      case ADD_STD_TIMINGS:
-	det_mon[i].type = DS_STD_TIMINGS;
-	get_dst_timing_section(c,det_mon[i].section.std_t, ver);
-	break;
-      case COLOR_MANAGEMENT_DATA:
-	det_mon[i].type = DS_CMD;
-	break;
-      case CVT_3BYTE_DATA:
-	det_mon[i].type = DS_CVT;
-	get_cvt_timing_section(c, det_mon[i].section.cvt);
-	break;
-      case ADD_EST_TIMINGS:
-	det_mon[i].type = DS_EST_III;
-	break;
-      case ADD_DUMMY:
-	det_mon[i].type = DS_DUMMY;
-        break;
-      default:
-        det_mon[i].type = DS_UNKOWN;
-        break;
-      }
-      if (c[3] <= 0x0F) {
-	det_mon[i].type = DS_VENDOR + c[3];
-      }
-    } else { 
-      det_mon[i].type = DT;
-      get_detailed_timing_section(c,&det_mon[i].section.d_timings);
+    for (i=0; i < DET_TIMINGS; i++) {
+        fetch_detailed_block(c, ver, det_mon + i);
+        NEXT_DT_MD_SECTION;
     }
-    NEXT_DT_MD_SECTION;
-  }
 }
 
 static void
diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h
index 07411b8..b865e1a 100644
--- a/hw/xfree86/ddc/xf86DDC.h
+++ b/hw/xfree86/ddc/xf86DDC.h
@@ -62,4 +62,9 @@ extern _X_EXPORT DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
 extern _X_EXPORT Bool
 xf86MonitorIsHDMI(xf86MonPtr mon);
 
+typedef void (* handle_detailed_fn)(struct detailed_monitor_section *,void *);
+
+void xf86ForEachDetailedBlock(xf86MonPtr mon,
+                              handle_detailed_fn,
+                              void *data);
 #endif
-- 
1.5.4.4





More information about the xorg-devel mailing list