Index: xf86DDC.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/ddc/xf86DDC.c,v retrieving revision 1.7 diff -u -r1.7 xf86DDC.c --- xf86DDC.c 18 Nov 2005 18:02:24 -0000 1.7 +++ xf86DDC.c 3 Jan 2006 23:21:30 -0000 @@ -119,16 +119,35 @@ int len ); +static void +EDIDDump(int scrnIndex, xf86MonPtr DDC); + +/* Pure for testing/debugging. No user should ever do this. */ +#define HAVEEDIDLOAD 1 + +#ifdef HAVEEDIDLOAD +static unsigned char * EDIDLoad(int scrnIndex, char *FileName); +#endif + typedef enum { DDCOPT_NODDC1, DDCOPT_NODDC2, - DDCOPT_NODDC + DDCOPT_NODDC, +#ifdef HAVEEDIDLOAD + DDCOPT_LOAD, +#endif + DDCOPT_DUMP } DDCOpts; static const OptionInfoRec DDCOptions[] = { { DDCOPT_NODDC1, "NoDDC1", OPTV_BOOLEAN, {0}, FALSE }, { DDCOPT_NODDC2, "NoDDC2", OPTV_BOOLEAN, {0}, FALSE }, { DDCOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE }, +#ifdef HAVEEDIDLOAD + { DDCOPT_LOAD, "LoadDDC", OPTV_ANYSTR, {0}, FALSE }, +#endif + { DDCOPT_DUMP, "DumpDDC", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE }, }; @@ -152,8 +171,11 @@ xf86MonPtr tmp = NULL; int sigio; /* Default DDC and DDC1 to enabled. */ - Bool noddc = FALSE, noddc1 = FALSE; + Bool noddc = FALSE, noddc1 = FALSE, dump; OptionInfoPtr options; +#ifdef HAVEEDIDLOAD + char *LoadName = NULL; +#endif options = xnfalloc(sizeof(DDCOptions)); (void)memcpy(options, DDCOptions, sizeof(DDCOptions)); @@ -161,15 +183,28 @@ xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); xf86GetOptValBool(options, DDCOPT_NODDC1, &noddc1); + dump = xf86ReturnOptValBool(options, DDCOPT_DUMP, FALSE); + +#ifdef HAVEEDIDLOAD + LoadName = xf86GetOptValString(options, DDCOPT_LOAD); +#endif + xfree(options); if (noddc || noddc1) return NULL; - - sigio = xf86BlockSIGIO(); - EDID_block = EDIDRead_DDC1(pScrn,DDC1SetSpeed,DDC1Read); - xf86UnblockSIGIO(sigio); +#ifdef HAVEEDIDLOAD + if (LoadName) + EDID_block = EDIDLoad(scrnIndex, LoadName); +#endif + + if (!EDID_block) { + sigio = xf86BlockSIGIO(); + EDID_block = EDIDRead_DDC1(pScrn,DDC1SetSpeed,DDC1Read); + xf86UnblockSIGIO(sigio); + } + if (EDID_block){ tmp = xf86InterpretEDID(scrnIndex,EDID_block); } @@ -178,7 +213,11 @@ if (!tmp) ErrorF("Cannot interpret EDID block\n"); #endif - return tmp; + + if (tmp && dump) + EDIDDump(scrnIndex, tmp); + + return tmp; } xf86MonPtr @@ -189,8 +228,11 @@ unsigned char *VDIF_Block = NULL; xf86MonPtr tmp = NULL; /* Default DDC and DDC2 to enabled. */ - Bool noddc = FALSE, noddc2 = FALSE; + Bool noddc = FALSE, noddc2 = FALSE, dump; OptionInfoPtr options; +#ifdef HAVEEDIDLOAD + char *LoadName = NULL; +#endif options = xnfalloc(sizeof(DDCOptions)); (void)memcpy(options, DDCOptions, sizeof(DDCOptions)); @@ -198,12 +240,24 @@ xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2); + dump = xf86ReturnOptValBool(options, DDCOPT_DUMP, FALSE); + +#ifdef HAVEEDIDLOAD + LoadName = xf86GetOptValString(options, DDCOPT_LOAD); +#endif + xfree(options); if (noddc || noddc2) return NULL; - EDID_block = EDID1Read_DDC2(scrnIndex,pBus); +#ifdef HAVEEDIDLOAD + if (LoadName) + EDID_block = EDIDLoad(scrnIndex, LoadName); +#endif + + if (!EDID_block) + EDID_block = EDID1Read_DDC2(scrnIndex,pBus); if (EDID_block){ tmp = xf86InterpretEDID(scrnIndex,EDID_block); @@ -224,7 +278,10 @@ VDIFRead(scrnIndex, pBus, EDID1_LEN * (tmp->no_sections + 1)); tmp->vdif = xf86InterpretVdif(VDIF_Block); } - + + if (tmp && dump) + EDIDDump(scrnIndex, tmp); + return tmp; } @@ -385,3 +442,58 @@ xfree(R_Buffer); return NULL; } + +/* + * Provide a means to dump edid blocks for debugging use. + */ +static void +EDIDDump(int scrnIndex, xf86MonPtr DDC) +{ + XF86FILE *EdidFile = NULL; + char FileName[20]; + + xf86snprintf(FileName, 20, "/tmp/%s-%04X.edid", DDC->vendor.name, + DDC->vendor.prod_id); + + xf86DrvMsg(scrnIndex, X_INFO, "Dumping EDID block to %s\n", FileName); + + EdidFile = xf86fopen(FileName, "w"); + if (!EdidFile) { + xf86DrvMsg(scrnIndex, X_WARNING, "Failed to open %s\n", FileName); + return; + } + + xf86fwrite(DDC->rawData, EDID1_LEN, 1, EdidFile); + xf86fclose(EdidFile); +} + +#ifdef HAVEEDIDLOAD +/* + * This one allows devs to easily test different edid blocks. + */ +static unsigned char * +EDIDLoad(int scrnIndex, char *FileName) +{ + XF86FILE *EdidFile = NULL; + unsigned char *Edid = NULL; + + xf86DrvMsg(scrnIndex, X_WARNING, "Loading %s for DDC information.\n", FileName); + xf86DrvMsg(scrnIndex, X_WARNING, "This should only be used for testing!\n"); + + EdidFile = xf86fopen(FileName, "r"); + if (!EdidFile) { + xf86DrvMsg(scrnIndex, X_WARNING, "Failed to open %s\n", FileName); + return NULL; + } + + Edid = xnfalloc(EDID1_LEN); + + if (EDID1_LEN != xf86fread(Edid, 1, EDID1_LEN, EdidFile)) { + xf86DrvMsg(scrnIndex, X_WARNING, "Failed to read from %s\n", FileName); + xfree(Edid); + return NULL; + } + + return Edid; +} +#endif