...

Source file src/github.com/anoopengineer/edidparser/edid/edidparser.go

Documentation: github.com/anoopengineer/edidparser/edid

     1  package edid
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"os"
     8  	"strconv"
     9  	"strings"
    10  	"text/tabwriter"
    11  )
    12  
    13  var TimingBitMap1 = []string{
    14  	"720×400 @ 70 Hz",
    15  	"720×400 @ 88 Hz",
    16  	"640×480 @ 60 Hz",
    17  	"640×480 @ 67 Hz",
    18  	"640×480 @ 72 Hz",
    19  	"640×480 @ 75 Hz",
    20  	"800×600 @ 56 Hz",
    21  	"800×600 @ 60 Hz"}
    22  
    23  var TimingBitMap2 = []string{
    24  	"800×600 @ 72 Hz",
    25  	"800×600 @ 75 Hz",
    26  	"832×624 @ 75 Hz",
    27  	"1024×768 @ 87 Hz, interlaced (1024×768i)",
    28  	"1024×768 @ 60 Hz",
    29  	"1024×768 @ 72 Hz",
    30  	"1024×768 @ 75 Hz",
    31  	"1280×1024 @ 75 Hz"}
    32  
    33  type MonitorRangeLimitDescriptor struct {
    34  	MinimumVerticalFieldRate  byte
    35  	MaximumVerticalFieldRate  byte
    36  	MinimumHorizontalLineRate byte
    37  	MaximumHorizontalLineRate byte
    38  	MaximumPixelClockRate     byte
    39  }
    40  
    41  type DetailedTimingDescriptor struct {
    42  	PixelClock               uint32
    43  	HorizontalActive         uint16
    44  	HorizontalBlanking       uint16
    45  	VerticalActive           uint16
    46  	VerticalBlanking         uint16
    47  	HorizontalSyncOffset     uint16
    48  	HorizontalSyncPulseWidth uint16
    49  	VerticalSyncOffset       uint16
    50  	VerticalSyncPulseWidth   uint16
    51  	HorizontalImageSize      uint16
    52  	VerticalImageSize        uint16
    53  	HorizontalBorder         byte
    54  	VerticalBorder           byte
    55  	Interlaced               bool
    56  	Stereo                   string
    57  	SyncType                 byte
    58  	HorizontalSyncPolarity   bool
    59  	VerticalSyncPolarity     bool
    60  }
    61  
    62  type Edid struct {
    63  	CheckSum          bool
    64  	Header            [8]byte
    65  	ManufacturerId    string
    66  	ProductCode       uint16
    67  	SerialNumber      uint32
    68  	WeekOfManufacture byte
    69  	YearOfManufacture uint
    70  	EdidVersion       byte
    71  	EdidRevision      byte
    72  
    73  	DigitalInput      bool
    74  	VESADFPCompatible bool
    75  
    76  	CompositeSyncSupported bool
    77  	SyncOnGreenSupported   bool
    78  
    79  	MaximumHorizontalImageSize byte
    80  	MaximumVerticalImageSize   byte
    81  	DisplayGamma               float32
    82  
    83  	DPMSStandbySupported   bool
    84  	DPMSSuspendSupported   bool
    85  	DPMSActiveOffSupported bool
    86  	DisplayType            string
    87  
    88  	RedX   float64
    89  	RedY   float64
    90  	GreenX float64
    91  	GreenY float64
    92  	BlueX  float64
    93  	BlueY  float64
    94  	WhiteX float64
    95  	WhiteY float64
    96  
    97  	TimingBitMap1 byte
    98  	TimingBitMap2 byte
    99  	TimingBitMap3 byte
   100  
   101  	StandardTimingInformation []string
   102  
   103  	DetailedTimingDescriptors []DetailedTimingDescriptor
   104  
   105  	MonitorName         string
   106  	MonitorSerialNumber string
   107  
   108  	MonitorRangeLimitDescriptors []MonitorRangeLimitDescriptor
   109  
   110  	NumberOfExtensions byte
   111  }
   112  
   113  func NewEdid(edidBytes []byte) (*Edid, error) {
   114  	edid := new(Edid)
   115  	for i := 0; i < 8; i++ {
   116  		edid.Header[i] = edidBytes[i]
   117  	}
   118  
   119  	//check the checksum
   120  	var checkSum byte
   121  	checkSum = 0
   122  	for i := 0; i < 128; i++ {
   123  		checkSum += edidBytes[i]
   124  	}
   125  	if checkSum == 0 {
   126  		edid.CheckSum = true
   127  	} else {
   128  		edid.CheckSum = false
   129  	}
   130  
   131  	manufacturerId := edidBytes[8:10]
   132  	edid.ManufacturerId = fmt.Sprintf("%c%c%c", (manufacturerId[0]>>2&0x1f)+'A'-1, (((manufacturerId[0]&0x3)<<3)|((manufacturerId[1]&0xe0)>>5))+'A'-1, (manufacturerId[1]&0x1f)+'A'-1)
   133  
   134  	p := bytes.NewBuffer(edidBytes)
   135  	//skip header and manufacturer id
   136  	p.Next(10)
   137  
   138  	var productCode uint16
   139  	binary.Read(p, binary.LittleEndian, &productCode)
   140  	edid.ProductCode = productCode
   141  
   142  	var serialNumber uint32
   143  	binary.Read(p, binary.LittleEndian, &serialNumber)
   144  	edid.SerialNumber = serialNumber
   145  
   146  	var weekOfManufacture byte
   147  	binary.Read(p, binary.LittleEndian, &weekOfManufacture)
   148  	edid.WeekOfManufacture = weekOfManufacture
   149  
   150  	var yearOfManufacture byte
   151  	binary.Read(p, binary.LittleEndian, &yearOfManufacture)
   152  	edid.YearOfManufacture = uint(yearOfManufacture) + 1990
   153  
   154  	var edidVersion byte
   155  	binary.Read(p, binary.LittleEndian, &edidVersion)
   156  	edid.EdidVersion = edidVersion
   157  
   158  	var edidRevision byte
   159  	binary.Read(p, binary.LittleEndian, &edidRevision)
   160  	edid.EdidRevision = edidRevision
   161  
   162  	var displayParam byte
   163  	binary.Read(p, binary.LittleEndian, &displayParam)
   164  	if displayParam&0x80 > 0 {
   165  		edid.DigitalInput = true
   166  		if displayParam&0x1 > 0 {
   167  			edid.VESADFPCompatible = true
   168  		}
   169  	} else {
   170  		edid.DigitalInput = false
   171  		if displayParam&0x4 > 0 {
   172  			edid.CompositeSyncSupported = true
   173  		}
   174  		if displayParam&0x2 > 0 {
   175  			edid.SyncOnGreenSupported = true
   176  		}
   177  
   178  	}
   179  
   180  	var horizontalDisplaySize byte
   181  	binary.Read(p, binary.LittleEndian, &horizontalDisplaySize)
   182  	edid.MaximumHorizontalImageSize = horizontalDisplaySize
   183  
   184  	var verticalDisplaySize byte
   185  	binary.Read(p, binary.LittleEndian, &verticalDisplaySize)
   186  	edid.MaximumVerticalImageSize = verticalDisplaySize
   187  
   188  	var displayGamma byte
   189  	binary.Read(p, binary.LittleEndian, &displayGamma)
   190  	edid.DisplayGamma = (float32(displayGamma) / 100) + 1
   191  
   192  	var featureBitmap byte
   193  	binary.Read(p, binary.LittleEndian, &featureBitmap)
   194  	if featureBitmap&0x80 > 0 {
   195  		edid.DPMSStandbySupported = true
   196  	}
   197  	if featureBitmap&0x40 > 0 {
   198  		edid.DPMSSuspendSupported = true
   199  	}
   200  	if featureBitmap&0x20 > 0 {
   201  		edid.DPMSActiveOffSupported = true
   202  	}
   203  
   204  	dispType := (featureBitmap & 0x18) >> 3
   205  
   206  	if edid.DigitalInput {
   207  		switch dispType {
   208  		case 0:
   209  			edid.DisplayType = "RGB 4:4:4"
   210  		case 1:
   211  			edid.DisplayType = "RGB 4:4:4 + YCrCb 4:4:4"
   212  		case 2:
   213  			edid.DisplayType = "RGB 4:4:4 + YCrCb 4:2:2"
   214  		case 3:
   215  			edid.DisplayType = "RGB 4:4:4 + YCrCb 4:4:4 + YCrCb 4:2:2"
   216  		}
   217  	} else {
   218  		switch dispType {
   219  		case 0:
   220  			edid.DisplayType = "Monochrome/Grayscale"
   221  		case 1:
   222  			edid.DisplayType = "RGB color"
   223  		case 2:
   224  			edid.DisplayType = "Non-RGB color"
   225  		case 3:
   226  			edid.DisplayType = "Undefined"
   227  		}
   228  	}
   229  
   230  	//25
   231  	var redGreenLSB byte
   232  	binary.Read(p, binary.LittleEndian, &redGreenLSB)
   233  
   234  	//26
   235  	var blueWhiteLSB byte
   236  	binary.Read(p, binary.LittleEndian, &blueWhiteLSB)
   237  
   238  	//27
   239  	var redXMSB byte
   240  	binary.Read(p, binary.LittleEndian, &redXMSB)
   241  
   242  	//28
   243  	var redYMSB byte
   244  	binary.Read(p, binary.LittleEndian, &redYMSB)
   245  
   246  	//29
   247  	var greenXMSB byte
   248  	binary.Read(p, binary.LittleEndian, &greenXMSB)
   249  
   250  	//30
   251  	var greenYMSB byte
   252  	binary.Read(p, binary.LittleEndian, &greenYMSB)
   253  
   254  	//31
   255  	var blueXMSB byte
   256  	binary.Read(p, binary.LittleEndian, &blueXMSB)
   257  
   258  	//32
   259  	var blueYMSB byte
   260  	binary.Read(p, binary.LittleEndian, &blueYMSB)
   261  
   262  	//33
   263  	var whiteXMSB byte
   264  	binary.Read(p, binary.LittleEndian, &whiteXMSB)
   265  
   266  	//34
   267  	var whiteYMSB byte
   268  	binary.Read(p, binary.LittleEndian, &whiteYMSB)
   269  
   270  	edid.RedX = float64((uint16(redXMSB)<<2)|((uint16(redGreenLSB)>>6)&0x3)) / 1024
   271  	edid.RedY = float64((uint16(redYMSB)<<2)|((uint16(redGreenLSB)>>4)&0x3)) / 1024
   272  	edid.GreenX = float64((uint16(greenXMSB)<<2)|((uint16(redGreenLSB)>>2)&0x3)) / 1024
   273  	edid.GreenY = float64((uint16(greenYMSB)<<2)|(uint16(redGreenLSB)&0x3)) / 1024
   274  	edid.BlueX = float64((uint16(blueXMSB)<<2)|((uint16(blueWhiteLSB)>>6)&0x3)) / 1024
   275  	edid.BlueY = float64((uint16(blueYMSB)<<2)|((uint16(blueWhiteLSB)>>4)&0x3)) / 1024
   276  	edid.WhiteX = float64((uint16(whiteXMSB)<<2)|((uint16(blueWhiteLSB)>>2)&0x3)) / 1024
   277  	edid.WhiteY = float64((uint16(whiteYMSB)<<2)|(uint16(blueWhiteLSB)&0x3)) / 1024
   278  
   279  	binary.Read(p, binary.LittleEndian, &edid.TimingBitMap1)
   280  	binary.Read(p, binary.LittleEndian, &edid.TimingBitMap2)
   281  	binary.Read(p, binary.LittleEndian, &edid.TimingBitMap3)
   282  
   283  	for i := 0; i < 8; i++ {
   284  		var temp byte
   285  		binary.Read(p, binary.LittleEndian, &temp)
   286  		xResolution := (uint(temp) + 31) * 8
   287  		binary.Read(p, binary.LittleEndian, &temp)
   288  		pixelRatio := temp >> 6
   289  		verticalFrequency := (uint(temp) & 63) + 60
   290  		var yResolution uint
   291  		var pixelRatioStr string
   292  
   293  		switch pixelRatio {
   294  		case 0:
   295  			//16:10
   296  			yResolution = xResolution * 10 / 16
   297  			pixelRatioStr = "16:10"
   298  		case 1:
   299  			//4:3
   300  			pixelRatioStr = "4:3"
   301  			yResolution = xResolution * 3 / 4
   302  		case 2:
   303  			//5:4
   304  			pixelRatioStr = "5:4"
   305  			yResolution = xResolution * 4 / 5
   306  		case 3:
   307  			//16:9
   308  			pixelRatioStr = "16:9"
   309  			yResolution = xResolution * 9 / 16
   310  
   311  		}
   312  		edid.StandardTimingInformation = append(edid.StandardTimingInformation, fmt.Sprintf("%dx%d %s @%dHz", xResolution, yResolution, pixelRatioStr, verticalFrequency))
   313  
   314  	}
   315  
   316  	//read 4 descriptors
   317  
   318  	for i := 0; i < 4; i++ {
   319  		var temp [18]byte
   320  		var descriptor DetailedTimingDescriptor
   321  		binary.Read(p, binary.LittleEndian, &temp)
   322  		descriptor.PixelClock = ((uint32(temp[1]) << 8) | uint32(temp[0])) * 10
   323  		descriptor.HorizontalActive = (uint16(temp[4]&240) << 4) | uint16(temp[2])
   324  		descriptor.HorizontalBlanking = (uint16(temp[4]&15) << 8) | uint16(temp[3])
   325  		descriptor.VerticalActive = (uint16(temp[7]&240) << 4) | uint16(temp[5])
   326  		descriptor.VerticalBlanking = (uint16(temp[7]&15) << 8) | uint16(temp[6])
   327  		descriptor.HorizontalSyncOffset = ((uint16(temp[11]) & 192) << 2) | uint16(temp[8])
   328  		descriptor.HorizontalSyncPulseWidth = ((uint16(temp[11]) & 48) << 4) | uint16(temp[9])
   329  		descriptor.VerticalSyncOffset = ((uint16(temp[11]) & 12) << 2) | ((uint16(temp[10]) & 240) >> 4)
   330  		descriptor.VerticalSyncPulseWidth = ((uint16(temp[11]) & 3) << 4) | (uint16(temp[10]) & 15)
   331  		descriptor.HorizontalImageSize = ((uint16(temp[14]) & 240) << 4) | uint16(temp[12])
   332  		descriptor.VerticalImageSize = ((uint16(temp[14]) & 15) << 8) | uint16(temp[13])
   333  		descriptor.HorizontalBorder = temp[15]
   334  		descriptor.VerticalBorder = temp[16]
   335  		descriptor.Interlaced = (temp[17] & 128) > 0
   336  		zeroBit := temp[17] & 1
   337  		stereoMode := (temp[17] & 96) >> 5
   338  		if stereoMode == 0 {
   339  			descriptor.Stereo = "No Stereo"
   340  		} else {
   341  			if zeroBit == 1 {
   342  				switch stereoMode {
   343  				case 1:
   344  					descriptor.Stereo = "2-way interleaved stereo - Right image on even lines"
   345  				case 2:
   346  					descriptor.Stereo = "2-way interleaved stereo - Left image on even lines"
   347  				case 3:
   348  					descriptor.Stereo = "2-way interleaved stereo - side-by-side"
   349  				}
   350  
   351  			} else {
   352  				switch stereoMode {
   353  				case 1:
   354  					descriptor.Stereo = "Field sequential, sync=1 during right"
   355  				case 2:
   356  					descriptor.Stereo = "similar, sync=1 during left"
   357  				case 3:
   358  					descriptor.Stereo = "4-way interleaved stereo"
   359  				}
   360  			}
   361  		}
   362  
   363  		descriptor.SyncType = (temp[17] & 24) >> 3
   364  		descriptor.VerticalSyncPolarity = ((temp[17] & 4) >> 2) > 0
   365  		descriptor.HorizontalSyncPolarity = ((temp[17] & 2) >> 1) > 0
   366  
   367  		if descriptor.PixelClock == 0 {
   368  			descriptorType := temp[3]
   369  			switch descriptorType {
   370  			case 0xFF:
   371  				edid.MonitorSerialNumber = string(temp[5:])
   372  			case 0xFC:
   373  				mon := string(temp[5:])
   374  				mon = strings.Replace(mon, "\n", "", -1)
   375  				mon = strings.TrimSpace(mon)
   376  				edid.MonitorName = mon
   377  			case 0xFD:
   378  				//Monitor range limits
   379  				var monitorRangeDescriptor MonitorRangeLimitDescriptor
   380  				monitorRangeDescriptor.MinimumVerticalFieldRate = temp[5]
   381  				monitorRangeDescriptor.MaximumVerticalFieldRate = temp[6]
   382  				monitorRangeDescriptor.MinimumHorizontalLineRate = temp[7]
   383  				monitorRangeDescriptor.MaximumHorizontalLineRate = temp[8]
   384  				monitorRangeDescriptor.MaximumPixelClockRate = temp[9] * 10
   385  				edid.MonitorRangeLimitDescriptors = append(edid.MonitorRangeLimitDescriptors, monitorRangeDescriptor)
   386  			}
   387  		} else {
   388  			edid.DetailedTimingDescriptors = append(edid.DetailedTimingDescriptors, descriptor)
   389  		}
   390  	}
   391  
   392  	binary.Read(p, binary.LittleEndian, &edid.NumberOfExtensions)
   393  	return edid, nil
   394  }
   395  
   396  func (edid *Edid) PrintableHeader() string {
   397  	var buffer bytes.Buffer
   398  	buffer.WriteString("0x")
   399  	for i := 0; i < len(edid.Header); i++ {
   400  		s := fmt.Sprintf("%02X", edid.Header[i])
   401  		buffer.WriteString(s)
   402  	}
   403  	return buffer.String()
   404  }
   405  
   406  func (e *Edid) PrettyPrint() {
   407  	w := new(tabwriter.Writer)
   408  	w.Init(os.Stdout, 30, 20, 4, '-', 0)
   409  	fmt.Fprintln(w, "Valid Checksum: \t ", e.CheckSum)
   410  	fmt.Fprintln(w, "Header: \t ", e.PrintableHeader())
   411  	fmt.Fprintln(w, "Monitor Name: \t ", e.MonitorName)
   412  	fmt.Fprintln(w, "Monitor Serial Number: \t ", e.MonitorSerialNumber)
   413  	fmt.Fprintln(w, "Manufacturer Name: \t ", e.ManufacturerId)
   414  	fmt.Fprintln(w, "Product Code: \t ", e.ProductCode)
   415  	fmt.Fprintln(w, "Serial Number: \t ", e.SerialNumber)
   416  	fmt.Fprintln(w, "Week of Manufacture: \t ", e.WeekOfManufacture)
   417  	fmt.Fprintln(w, "Year of Manufacture: \t ", e.YearOfManufacture)
   418  	fmt.Fprintln(w, "EDID Version: \t ", e.EdidVersion)
   419  	fmt.Fprintln(w, "EDID Revision: \t ", e.EdidRevision)
   420  	fmt.Fprintln(w, "\nBasic display parameters:\n")
   421  
   422  	if e.DigitalInput {
   423  		fmt.Fprintln(w, "    Video Input Definition: \t ", "Digital")
   424  		fmt.Fprintln(w, "    VESA DFP Compatibility: \t ", e.VESADFPCompatible)
   425  	} else {
   426  		fmt.Fprintln(w, "    Video Input Definition: \t ", "Analog")
   427  		fmt.Fprintln(w, "    Composite Sync Supported: \t ", e.CompositeSyncSupported)
   428  		fmt.Fprintln(w, "    Sync on Green Supported: \t ", e.SyncOnGreenSupported)
   429  	}
   430  	fmt.Fprintln(w, "    Max Horizontal Image Size: \t ", e.MaximumHorizontalImageSize, "cm")
   431  	fmt.Fprintln(w, "    Max Vertical Image Size: \t ", e.MaximumVerticalImageSize, "cm")
   432  	fmt.Fprintln(w, "    Display Gamma: \t ", e.DisplayGamma)
   433  
   434  	fmt.Fprintln(w, "\nPower Management:")
   435  	fmt.Fprintln(w, "    DPMS Standby Supported: \t ", e.DPMSStandbySupported)
   436  	fmt.Fprintln(w, "    DPMS Suspend Supported: \t ", e.DPMSSuspendSupported)
   437  	fmt.Fprintln(w, "    DPMS Active Off Supported: \t ", e.DPMSActiveOffSupported)
   438  	fmt.Fprintln(w, "    Display Type: \t ", e.DisplayType)
   439  
   440  	fmt.Fprintln(w, "\nChroma Information:")
   441  	fmt.Fprintln(w, "    Red X: \t ", strconv.FormatFloat(e.RedX, 'f', 3, 64))
   442  	fmt.Fprintln(w, "    Red Y: \t ", strconv.FormatFloat(e.RedY, 'f', 3, 64))
   443  	fmt.Fprintln(w, "    Green X: \t ", strconv.FormatFloat(e.GreenX, 'f', 3, 64))
   444  	fmt.Fprintln(w, "    Green Y: \t ", strconv.FormatFloat(e.GreenY, 'f', 3, 64))
   445  	fmt.Fprintln(w, "    Blue X: \t ", strconv.FormatFloat(e.BlueX, 'f', 3, 64))
   446  	fmt.Fprintln(w, "    Blue Y: \t ", strconv.FormatFloat(e.BlueY, 'f', 3, 64))
   447  	fmt.Fprintln(w, "    White X: \t ", strconv.FormatFloat(e.WhiteX, 'f', 3, 64))
   448  	fmt.Fprintln(w, "    White Y: \t ", strconv.FormatFloat(e.WhiteY, 'f', 3, 64))
   449  
   450  	fmt.Fprintln(w, "\nTimings Bitmaps:")
   451  
   452  	counter := 0
   453  	var mask byte
   454  	for mask = 0x80; mask != 0; mask >>= 1 {
   455  		if e.TimingBitMap1&mask > 0 {
   456  			fmt.Fprintln(w, "    "+TimingBitMap1[counter])
   457  		}
   458  		counter++
   459  	}
   460  	counter = 0
   461  	for mask = 0x80; mask != 0; mask >>= 1 {
   462  		if e.TimingBitMap2&mask > 0 {
   463  			fmt.Fprintln(w, "    "+TimingBitMap2[counter])
   464  		}
   465  		counter++
   466  	}
   467  
   468  	if e.TimingBitMap3&0x80 > 0 {
   469  		fmt.Fprintln(w, "    1152x870 @ 75 Hz (Apple Macintosh II)")
   470  	}
   471  	fmt.Fprintln(w, "\nStandard Timing Identification:")
   472  	for _, element := range e.StandardTimingInformation {
   473  		fmt.Fprintln(w, "    ", element)
   474  	}
   475  
   476  	for index, element := range e.DetailedTimingDescriptors {
   477  		fmt.Fprintln(w, "\nDetailed Timing/Descriptor block", (index + 1))
   478  		fmt.Fprintln(w, "    Pixel Clock: \t ", element.PixelClock, "kHz")
   479  		fmt.Fprintln(w, "    Horizontal Active: \t ", element.HorizontalActive, "pixels")
   480  		fmt.Fprintln(w, "    Horizontal Blanking: \t ", element.HorizontalBlanking, "pixels")
   481  		fmt.Fprintln(w, "    Vertical Active: \t ", element.VerticalActive, "pixels")
   482  		fmt.Fprintln(w, "    Vertical Blanking: \t ", element.VerticalBlanking, "pixels")
   483  		fmt.Fprintln(w, "    Horizontal Sync Offset: \t ", element.HorizontalSyncOffset, "pixels")
   484  		fmt.Fprintln(w, "    Horizontal Sync Pulse Width: \t ", element.HorizontalSyncPulseWidth, "pixels")
   485  		fmt.Fprintln(w, "    Vertical Sync Offset: \t ", element.VerticalSyncOffset, "lines")
   486  		fmt.Fprintln(w, "    Vertical Sync Pulse Width: \t ", element.VerticalSyncPulseWidth, "lines")
   487  		fmt.Fprintln(w, "    Horizontal Image Size: \t ", element.HorizontalImageSize, "mm")
   488  		fmt.Fprintln(w, "    Vertical Image Size: \t ", element.VerticalImageSize, "mm")
   489  		fmt.Fprintln(w, "    Horizontal Border: \t ", element.HorizontalBorder, "px each side")
   490  		fmt.Fprintln(w, "    Vertical Border: \t ", element.VerticalBorder, "px each side")
   491  		fmt.Fprintln(w, "    Interlaced: \t ", element.Interlaced)
   492  		fmt.Fprintln(w, "    Stereo Mode: \t ", element.Stereo)
   493  		switch element.SyncType {
   494  		case 0:
   495  			fmt.Fprintln(w, "    Sync Type: \t ", "Analog composite")
   496  		case 1:
   497  			fmt.Fprintln(w, "    Sync Type: \t ", "Bipolar analog composite")
   498  		case 2:
   499  			fmt.Fprintln(w, "    Sync Type: \t ", "Digital composite (on HSync)")
   500  		case 3:
   501  			fmt.Fprintln(w, "    Sync Type: \t ", "Digital separate")
   502  			fmt.Fprintln(w, "    Vertical Sync Polarity: \t ", element.VerticalSyncPolarity)
   503  			fmt.Fprintln(w, "    Horizontal Sync Polarity: \t ", element.HorizontalSyncPolarity)
   504  		}
   505  
   506  	}
   507  
   508  	for index, element := range e.MonitorRangeLimitDescriptors {
   509  		fmt.Fprintln(w, "\nMonitor range limits descriptor block", (index + 1))
   510  		fmt.Fprintln(w, "    Minimum Vertical Field Rate: \t ", element.MinimumVerticalFieldRate, "Hz")
   511  		fmt.Fprintln(w, "    Maximum Vertical Field Rate: \t ", element.MaximumVerticalFieldRate, "Hz")
   512  		fmt.Fprintln(w, "    Minimum Horizontal Line Rate: \t ", element.MinimumHorizontalLineRate, "kHz")
   513  		fmt.Fprintln(w, "    Maximum Horizontal Line Rate: \t ", element.MaximumHorizontalLineRate, "kHz")
   514  		fmt.Fprintln(w, "    Maximum Pixel Clock Rate: \t ", element.MaximumPixelClockRate, "MHz")
   515  	}
   516  	fmt.Fprintln(w, "\nTotal Number of Extensions: \t ", e.NumberOfExtensions, "(not parsed)")
   517  
   518  	fmt.Fprintln(w, "\n**************************************************************************")
   519  	fmt.Fprintln(w, "*                Bugs? Contact anoopengineer@gmail.com                   *")
   520  	fmt.Fprintln(w, "**************************************************************************\n")
   521  	w.Flush()
   522  }
   523  

View as plain text