xserver/hw/xorg/ddc Makefile.am, NONE, 1.1 ddcPriv.h, NONE,
1.1 ddcProperty.c, NONE, 1.1 edid.c, NONE, 1.1 edid.h, NONE,
1.1 interpret_edid.c, NONE, 1.1 interpret_vdif.c, NONE,
1.1 print_edid.c, NONE, 1.1 print_vdif.c, NONE, 1.1 vdif.h,
NONE, 1.1 xf86DDC.c, NONE, 1.1 xf86DDC.h, NONE, 1.1
Daniel Stone
xserver-commit at pdx.freedesktop.org
Sun Apr 25 23:52:16 EST 2004
- Previous message: xserver/hw/xorg/common Makefile.am, NONE, 1.1 atKeynames.h, NONE,
1.1 compiler.h, NONE, 1.1 fourcc.h, NONE, 1.1 xf86.h, NONE,
1.1 xf86Bus.c, NONE, 1.1 xf86Bus.h, NONE, 1.1 xf86Config.c,
NONE, 1.1 xf86Config.h, NONE, 1.1 xf86Configure.c, NONE,
1.1 xf86Cursor.c, NONE, 1.1 xf86DGA.c, NONE, 1.1 xf86DPMS.c,
NONE, 1.1 xf86Debug.c, NONE, 1.1 xf86DefModes.c, NONE,
1.1 xf86DoProbe.c, NONE, 1.1 xf86DoScanPci.c, NONE,
1.1 xf86Events.c, NONE, 1.1 xf86Globals.c, NONE,
1.1 xf86Helper.c, NONE, 1.1 xf86InPriv.h, NONE, 1.1 xf86Init.c,
NONE, 1.1 xf86Io.c, NONE, 1.1 xf86Kbd.c, NONE,
1.1 xf86KbdBSD.c, NONE, 1.1 xf86KbdLnx.c, NONE,
1.1 xf86KbdMach.c, NONE, 1.1 xf86Keymap.h, NONE,
1.1 xf86MiscExt.c, NONE, 1.1 xf86Mode.c, NONE,
1.1 xf86Module.h, NONE, 1.1 xf86Opt.h, NONE, 1.1 xf86Option.c,
NONE, 1.1 xf86PM.c, NONE, 1.1 xf86PciInfo.h, NONE,
1.1 xf86Priv.h, NONE, 1.1 xf86Privstr.h, NONE, 1.1 xf86RandR.c,
NONE, 1.1 xf86Resources.h, NONE, 1.1 xf86Versions.c, NONE,
1.1 xf86VidMode.c, NONE, 1.1 xf86XKB.c, NONE, 1.1 xf86Xinput.c,
NONE, 1.1 xf86Xinput.h, NONE, 1.1 xf86bigfont.c, NONE,
1.1 xf86cmap.c, NONE, 1.1 xf86cmap.h, NONE, 1.1 xf86dga.c,
NONE, 1.1 xf86dga2.c, NONE, 1.1 xf86dgaext.h, NONE,
1.1 xf86fbBus.c, NONE, 1.1 xf86fbman.c, NONE, 1.1 xf86fbman.h,
NONE, 1.1 xf86isaBus.c, NONE, 1.1 xf86misc.c, NONE,
1.1 xf86miscproc.h, NONE, 1.1 xf86noBus.c, NONE,
1.1 xf86pciBus.c, NONE, 1.1 xf86pciBus.h, NONE,
1.1 xf86sbusBus.c, NONE, 1.1 xf86sbusBus.h, NONE,
1.1 xf86str.h, NONE, 1.1 xf86vmode.c, NONE, 1.1 xf86xv.c, NONE,
1.1 xf86xv.h, NONE, 1.1 xf86xvmc.c, NONE, 1.1 xf86xvmc.h, NONE,
1.1 xf86xvpriv.h, NONE, 1.1 xisb.c, NONE, 1.1 xisb.h, NONE, 1.1
- Next message: xserver/hw/xorg/drivers Imakefile, NONE, 1.1 Makefile.am, NONE,
1.1 confdrv.sh, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: daniel
Update of /cvs/xserver/xserver/hw/xorg/ddc
In directory pdx:/tmp/cvs-serv17025/hw/xorg/ddc
Added Files:
Makefile.am ddcPriv.h ddcProperty.c edid.c edid.h
interpret_edid.c interpret_vdif.c print_edid.c print_vdif.c
vdif.h xf86DDC.c xf86DDC.h
Log Message:
Xizzle is dead, long live Xorg.
Re-import the DDX from X11R6.7, complete with automakey goodness, and do the
requisite configure.ac, et al, updates; also import the XKB extension from the
6.7 DIX.
Currently it'll link and then hang solid in RADEONInitAccel(), or the next
function if you enable NoAccel.
--- NEW FILE: Makefile.am ---
sdk_INCLUDEDIR = $(includedir)/xorg
sdk_INCLUDES = edid.h vdif.h xf86DDC.h
lib_LIBRARIES = libxorgddc.a
libxorgddc_a_SOURCES = xf86DDC.c edid.c interpret_edid.c print_edid.c \
interpret_vdif.c print_vdif.c ddcProperty.c
INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c
AM_CFLAGS = $(XORG_CFLAGS)
--- NEW FILE: ddcPriv.h ---
extern unsigned char *GetEDID_DDC1(
unsigned int *
);
extern int DDC_checksum(
unsigned char *,
int
);
--- NEW FILE: ddcProperty.c ---
/* ddcProperty.c: Make the DDC monitor information available to clients
* as properties on the root window
*
* Copyright 1999 by Andrew C Aitchison <A.C.Aitchison at dpmms.cam.ac.uk>
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/ddcProperty.c,v 1.9tsi Exp $ */
#include "misc.h"
#include "xf86.h"
/* #include "xf86_ansic.h" */
/* #include "xf86_OSproc.h" */
#include <X11/Xatom.h>
#include "property.h"
#include "propertyst.h"
#include "xf86DDC.h"
#define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA"
#define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA"
#define VDIF_ATOM_NAME "XFree86_DDC_VDIF_RAWDATA"
Bool
xf86SetDDCproperties(ScrnInfoPtr pScrnInfo, xf86MonPtr DDC)
{
Atom EDID1Atom=-1, EDID2Atom=-1, VDIFAtom=-1;
CARD8 *EDID1rawdata = NULL;
CARD8 *EDID2rawdata = NULL;
int i, ret;
Bool makeEDID1prop = FALSE;
Bool makeEDID2prop = FALSE;
#ifdef DEBUG
ErrorF("xf86SetDDCproperties(%p, %p)\n", pScrnInfo, DDC);
#endif
if (pScrnInfo==NULL || pScrnInfo->monitor==NULL || DDC==NULL) {
return FALSE;
}
#ifdef DEBUG
ErrorF("pScrnInfo->scrnIndex %d\n", pScrnInfo->scrnIndex);
ErrorF("pScrnInfo->monitor was %p\n", pScrnInfo->monitor);
#endif
pScrnInfo->monitor->DDC = DDC;
if (DDC->ver.version == 1) {
makeEDID1prop = TRUE;
} else if (DDC->ver.version == 2) {
int checksum1;
int checksum2;
makeEDID2prop = TRUE;
/* Some monitors (eg Panasonic PanaSync4)
* report version==2 because they used EDID v2 spec document,
* although they use EDID v1 data structure :-(
*
* Try using checksum to determine when we have such a monitor.
*/
checksum2 = 0;
for (i=0; i<256; i++) { checksum2 += DDC->rawData[i]; }
if ( (checksum2 % 256) != 0 ) {
xf86DrvMsg(pScrnInfo->scrnIndex,X_INFO, "Monitor EDID v2 checksum failed\n");
xf86DrvMsg(pScrnInfo->scrnIndex,X_INFO, "XFree86_DDC_EDID2_RAWDATA property may be bad\n");
checksum1 = 0;
for (i=0; i<128; i++) { checksum1 += DDC->rawData[i]; }
if ( (checksum1 % 256) == 0 ) {
xf86DrvMsg(pScrnInfo->scrnIndex,X_INFO, "Monitor EDID v1 checksum passed,\n");
xf86DrvMsg(pScrnInfo->scrnIndex,X_INFO, "XFree86_DDC_EDID1_RAWDATA property created\n");
makeEDID1prop = TRUE;
}
}
} else {
xf86DrvMsg(pScrnInfo->scrnIndex, X_PROBED,
"unexpected EDID version %d revision %d\n",
DDC->ver.version, DDC->ver.revision );
}
if (makeEDID1prop) {
if ( (EDID1rawdata = xalloc(128*sizeof(CARD8)))==NULL ) {
return FALSE;
}
EDID1Atom = MakeAtom(EDID1_ATOM_NAME, sizeof(EDID1_ATOM_NAME), TRUE);
for (i=0; i<128; i++) {
EDID1rawdata[i] = DDC->rawData[i];
}
#ifdef DEBUG
ErrorF("xf86RegisterRootWindowProperty %p(%d,%d,%d,%d,%d,%p)\n",
xf86RegisterRootWindowProperty,
pScrnInfo->scrnIndex,
EDID1Atom, XA_INTEGER, 8,
128, (unsigned char *)EDID1rawdata );
#endif
ret = xf86RegisterRootWindowProperty(pScrnInfo->scrnIndex,
EDID1Atom, XA_INTEGER, 8,
128, (unsigned char *)EDID1rawdata
);
if (ret != Success)
ErrorF("xf86RegisterRootWindowProperty returns %d\n", ret );
}
if (makeEDID2prop) {
if ( (EDID2rawdata = xalloc(256*sizeof(CARD8)))==NULL ) {
return FALSE;
}
for (i=0; i<256; i++) {
EDID2rawdata[i] = DDC->rawData[i];
}
EDID2Atom = MakeAtom(EDID2_ATOM_NAME, sizeof(EDID2_ATOM_NAME), TRUE);
#ifdef DEBUG
ErrorF("xf86RegisterRootWindowProperty %p(%d,%d,%d,%d,%d,%p)\n",
xf86RegisterRootWindowProperty,
pScrnInfo->scrnIndex,
EDID2Atom, XA_INTEGER, 8,
256, (unsigned char *)EDID2rawdata );
#endif
ret = xf86RegisterRootWindowProperty(pScrnInfo->scrnIndex,
EDID2Atom, XA_INTEGER, 8,
256, (unsigned char *)EDID2rawdata
);
if (ret != Success)
ErrorF("xf86RegisterRootWindowProperty returns %d\n", ret );
}
if (DDC->vdif) {
#define VDIF_DUMMY_STRING "setting dummy VDIF property - please insert correct values\n"
#ifdef DEBUG
ErrorF("xf86RegisterRootWindowProperty %p(%d,%d,%d,%d,%d,%p)\n",
xf86RegisterRootWindowProperty,
pScrnInfo->scrnIndex,
VDIFAtom, XA_STRING, 8,
strlen(VDIF_DUMMY_STRING), VDIF_DUMMY_STRING
);
#endif
VDIFAtom = MakeAtom(VDIF_ATOM_NAME, sizeof(VDIF_ATOM_NAME), TRUE);
ret = xf86RegisterRootWindowProperty(pScrnInfo->scrnIndex,
VDIFAtom, XA_STRING, 8,
strlen(VDIF_DUMMY_STRING),
VDIF_DUMMY_STRING
);
if (ret != Success)
ErrorF("xf86RegisterRootWindowProperty returns %d\n", ret );
}
return TRUE;
}
--- NEW FILE: edid.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/edid.c,v 1.3 2000/11/03 18:46:08 eich Exp $ */
/* edid.c: retrieve EDID record from raw DDC1 data stream: data
* is contained in an array of unsigned int each unsigned int
* contains one bit if bit is 0 unsigned int has to be zero else
* unsigned int > 0
*
* Copyright 1998 by Egbert Eich <Egbert.Eich at Physik.TU-Darmstadt.DE>
*/
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
#include "xf86DDC.h"
#include "ddcPriv.h"
static int find_start(unsigned int *);
static unsigned char * find_header(unsigned char *);
static unsigned char * resort(unsigned char *);
unsigned char *
GetEDID_DDC1(unsigned int *s_ptr)
{
unsigned char *d_block, *d_pos;
unsigned int *s_pos, *s_end;
int s_start;
int i,j;
s_start = find_start(s_ptr);
if (s_start==-1) return NULL;
s_end = s_ptr + NUM;
s_pos = s_ptr + s_start;
d_block=xalloc(EDID1_LEN);
if (!d_block) return NULL;
d_pos = d_block;
for (i=0;i<EDID1_LEN;i++) {
for (j=0;j<8;j++) {
*d_pos <<= 1;
if (*s_pos) {
*d_pos |= 0x01;
}
s_pos++; if (s_pos == s_end) s_pos=s_ptr;
};
s_pos++; if (s_pos == s_end) s_pos=s_ptr;
d_pos++;
}
xfree(s_ptr);
if (d_block && DDC_checksum(d_block,EDID1_LEN)) return NULL;
return (resort(d_block));
}
int
DDC_checksum(unsigned char *block, int len)
{
int i, result = 0;
int not_null = 0;
for (i=0;i<len;i++) {
not_null |= block[i];
result += block[i];
}
#ifdef DEBUG
if (result & 0xFF) ErrorF("DDC checksum not correct\n");
if (!not_null) ErrorF("DDC read all Null\n");
#endif
/* catch the trivial case where all bytes are 0 */
if (!not_null) return 1;
return (result&0xFF);
}
static int
find_start(unsigned int *ptr)
{
unsigned int comp[9], test[9];
int i,j;
for (i=0;i<9;i++){
comp[i] = *(ptr++);
test[i] = 1;
}
for (i=0;i<127;i++){
for (j=0;j<9;j++){
test[j] = test[j] & !(comp[j] ^ *(ptr++));
}
}
for (i=0;i<9;i++)
if (test[i]) return (i+1);
return (-1);
}
static unsigned char *
find_header(unsigned char *block)
{
unsigned char *ptr, *head_ptr, *end;
unsigned char header[]={0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
ptr = block;
end = block + EDID1_LEN;
while (ptr<end) {
int i;
head_ptr = ptr;
for (i=0;i<8;i++){
if (header[i] != *(head_ptr++)) break;
if (head_ptr == end) head_ptr = block;
}
if (i==8) break;
ptr++;
}
if (ptr == end) return (NULL);
return (ptr);
}
static unsigned char *
resort(unsigned char *s_block)
{
unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end;
unsigned char tmp;
s_end = s_block + EDID1_LEN;
d_new = xalloc(EDID1_LEN);
if (!d_new) return NULL;
d_end = d_new + EDID1_LEN;
s_ptr = find_header(s_block);
if (!s_ptr) return NULL;
for (d_ptr=d_new;d_ptr<d_end;d_ptr++){
tmp = *(s_ptr++);
*d_ptr = tmp;
if (s_ptr == s_end) s_ptr = s_block;
}
xfree(s_block);
return (d_new);
}
--- NEW FILE: edid.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/edid.h,v 1.6 2000/04/17 16:29:55 eich Exp $ */
/* edid.h: defines to parse an EDID block
*
* This file contains all information to interpret a standard EDIC block
* transmitted by a display device via DDC (Display Data Channel). So far
* there is no information to deal with optional EDID blocks.
* DDC is a Trademark of VESA (Video Electronics Standard Association).
*
* Copyright 1998 by Egbert Eich <Egbert.Eich at Physik.TU-Darmstadt.DE>
*/
#ifndef _EDID_H_
#define _EDID_H_ 1
#include "vdif.h"
/* read complete EDID record */
#define EDID1_LEN 128
#define BITS_PER_BYTE 9
#define NUM BITS_PER_BYTE*EDID1_LEN
#define HEADER 6
#define STD_TIMINGS 8
#define DET_TIMINGS 4
#ifdef _PARSE_EDID_
/* header: 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 */
#define HEADER_SECTION 0
#define HEADER_LENGTH 8
/* vendor section */
#define VENDOR_SECTION (HEADER_SECTION + HEADER_LENGTH)
#define V_MANUFACTURER 0
#define V_PROD_ID (V_MANUFACTURER + 2)
#define V_SERIAL (V_PROD_ID + 2)
#define V_WEEK (V_SERIAL + 4)
#define V_YEAR (V_WEEK + 1)
#define VENDOR_LENGTH (V_YEAR + 1)
/* EDID version */
#define VERSION_SECTION (VENDOR_SECTION + VENDOR_LENGTH)
#define V_VERSION 0
#define V_REVISION (V_VERSION + 1)
#define VERSION_LENGTH (V_REVISION + 1)
/* display information */
#define DISPLAY_SECTION (VERSION_SECTION + VERSION_LENGTH)
#define D_INPUT 0
#define D_HSIZE (D_INPUT + 1)
#define D_VSIZE (D_HSIZE + 1)
#define D_GAMMA (D_VSIZE + 1)
#define FEAT_S (D_GAMMA + 1)
#define D_RG_LOW (FEAT_S + 1)
#define D_BW_LOW (D_RG_LOW + 1)
#define D_REDX (D_BW_LOW + 1)
#define D_REDY (D_REDX + 1)
#define D_GREENX (D_REDY + 1)
#define D_GREENY (D_GREENX + 1)
#define D_BLUEX (D_GREENY + 1)
#define D_BLUEY (D_BLUEX + 1)
#define D_WHITEX (D_BLUEY + 1)
#define D_WHITEY (D_WHITEX + 1)
#define DISPLAY_LENGTH (D_WHITEY + 1)
/* supported VESA and other standard timings */
#define ESTABLISHED_TIMING_SECTION (DISPLAY_SECTION + DISPLAY_LENGTH)
#define E_T1 0
#define E_T2 (E_T1 + 1)
#define E_TMANU (E_T2 + 1)
#define E_TIMING_LENGTH (E_TMANU + 1)
/* non predefined standard timings supported by display */
#define STD_TIMING_SECTION (ESTABLISHED_TIMING_SECTION + E_TIMING_LENGTH)
#define STD_TIMING_INFO_LEN 2
#define STD_TIMING_INFO_NUM STD_TIMINGS
#define STD_TIMING_LENGTH (STD_TIMING_INFO_LEN * STD_TIMING_INFO_NUM)
/* detailed timing info of non standard timings */
#define DET_TIMING_SECTION (STD_TIMING_SECTION + STD_TIMING_LENGTH)
#define DET_TIMING_INFO_LEN 18
#define MONITOR_DESC_LEN DET_TIMING_INFO_LEN
#define DET_TIMING_INFO_NUM DET_TIMINGS
#define DET_TIMING_LENGTH (DET_TIMING_INFO_LEN * DET_TIMING_INFO_NUM)
/* number of EDID sections to follow */
#define NO_EDID (DET_TIMING_SECTION + DET_TIMING_LENGTH)
/* one byte checksum */
#define CHECKSUM (NO_EDID + 1)
#if (CHECKSUM != (EDID1_LEN - 1))
# error "EDID1 length != 128!"
#endif
#define SECTION(x,y) (Uchar *)(x + y)
#define GET_ARRAY(y) ((Uchar *)(c + y))
#define GET(y) *(Uchar *)(c + y)
/* extract information from vendor section */
#define _PROD_ID(x) x[0] + (x[1] << 8);
#define PROD_ID _PROD_ID(GET_ARRAY(V_PROD_ID))
#define _SERIAL_NO(x) x[0] + (x[1] << 8) + (x[2] << 16) + (x[3] << 24)
#define SERIAL_NO _SERIAL_NO(GET_ARRAY(V_SERIAL))
#define _YEAR(x) (x & 0xFF) + 1990
#define YEAR _YEAR(GET(V_YEAR))
#define WEEK GET(V_WEEK) & 0xFF
#define _L1(x) ((x[0] & 0x7C) >> 2) + '@'
#define _L2(x) ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@'
#define _L3(x) (x[1] & 0x1F) + '@';
#define L1 _L1(GET_ARRAY(V_MANUFACTURER))
#define L2 _L2(GET_ARRAY(V_MANUFACTURER))
#define L3 _L3(GET_ARRAY(V_MANUFACTURER))
/* extract information from version section */
#define VERSION GET(V_VERSION)
#define REVISION GET(V_REVISION)
/* extract information from display section */
#define _INPUT_TYPE(x) ((x & 0x80) >> 7)
#define INPUT_TYPE _INPUT_TYPE(GET(D_INPUT))
#define _INPUT_VOLTAGE(x) ((x & 0x60) >> 5)
#define INPUT_VOLTAGE _INPUT_VOLTAGE(GET(D_INPUT))
#define _SETUP(x) ((x & 0x10) >> 4)
#define SETUP _SETUP(GET(D_INPUT))
#define _SYNC(x) (x & 0x0F)
#define SYNC _SYNC(GET(D_INPUT))
#define _GAMMA(x) ((x + 100.0)/100.0)
#define GAMMA _GAMMA(GET(D_GAMMA))
#define HSIZE_MAX GET(D_HSIZE)
#define VSIZE_MAX GET(D_VSIZE)
#define _DPMS(x) ((x & 0xE0) >> 5)
#define DPMS _DPMS(GET(FEAT_S))
#define _DISPLAY_TYPE(x) ((x & 0x18) >> 3)
#define DISPLAY_TYPE _DISPLAY_TYPE(GET(FEAT_S))
#define _MSC(x) (x & 0x7)
#define MSC _MSC(GET(FEAT_S))
/* color characteristics */
#define CC_L(x,y) ((x & (0x03 << y)) >> y)
#define CC_H(x) (x << 2)
#define I_CC(x,y,z) CC_H(y) | CC_L(x,z)
#define F_CC(x) ((x)/1024.0)
#define REDX F_CC(I_CC((GET(D_RG_LOW)),(GET(D_REDX)),6))
#define REDY F_CC(I_CC((GET(D_RG_LOW)),(GET(D_REDY)),4))
#define GREENX F_CC(I_CC((GET(D_RG_LOW)),(GET(D_GREENX)),2))
#define GREENY F_CC(I_CC((GET(D_RG_LOW)),(GET(D_GREENY)),0))
#define BLUEX F_CC(I_CC((GET(D_BW_LOW)),(GET(D_BLUEX)),6))
#define BLUEY F_CC(I_CC((GET(D_BW_LOW)),(GET(D_BLUEY)),4))
#define WHITEX F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEX)),2))
#define WHITEY F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEY)),0))
/* extract information from standard timing section */
#define T1 GET(E_T1)
#define T2 GET(E_T2)
#define T_MANU GET(E_TMANU)
/* extract information from estabished timing section */
#define _HSIZE1(x) ((x[0] + 31) * 8)
#define HSIZE1 _HSIZE1(c)
#define RATIO(x) ((x[1] & 0xC0) >> 6)
#define RATIO1_1 0
#define RATIO4_3 1
#define RATIO5_4 2
#define RATIO16_9 3
#define _VSIZE1(x,y) switch(RATIO(x)){ \
case RATIO1_1: y = _HSIZE1(x); break; \
case RATIO4_3: y = _HSIZE1(x) * 3 / 4; break; \
case RATIO5_4: y = _HSIZE1(x) * 4 / 5; break; \
case RATIO16_9: y = _HSIZE1(x) * 9 / 16; break; \
}
#define VSIZE1(x) _VSIZE1(c,x)
#define _REFRESH_R(x) (x[1] & 0x3F) + 60
#define REFRESH_R _REFRESH_R(c)
#define _ID_LOW(x) x[0]
#define ID_LOW _ID_LOW(c)
#define _ID_HIGH(x) (x[1] << 8)
#define ID_HIGH _ID_HIGH(c)
#define STD_TIMING_ID (ID_LOW | ID_HIGH)
#define _NEXT_STD_TIMING(x) (x = (x + STD_TIMING_INFO_LEN))
#define NEXT_STD_TIMING _NEXT_STD_TIMING(c)
/* EDID Ver. > 1.2 */
#define _IS_MONITOR_DESC(x) (x[0] == 0 && x[1] == 0 && x[2] == 0 && x[4] == 0)
#define IS_MONITOR_DESC _IS_MONITOR_DESC(c)
#define _PIXEL_CLOCK(x) (x[0] + (x[1] << 8)) * 10000
#define PIXEL_CLOCK _PIXEL_CLOCK(c)
#define _H_ACTIVE(x) (x[2] + ((x[4] & 0xF0) << 4))
#define H_ACTIVE _H_ACTIVE(c)
#define _H_BLANK(x) (x[3] + ((x[4] & 0x0F) << 8))
#define H_BLANK _H_BLANK(c)
#define _V_ACTIVE(x) (x[5] + ((x[7] & 0xF0) << 4))
#define V_ACTIVE _V_ACTIVE(c)
#define _V_BLANK(x) (x[6] + ((x[7] & 0x0F) << 8))
#define V_BLANK _V_BLANK(c)
#define _H_SYNC_OFF(x) (x[8] + ((x[11] & 0xC0) << 2))
#define H_SYNC_OFF _H_SYNC_OFF(c)
#define _H_SYNC_WIDTH(x) (x[9] + ((x[11] & 0x30) << 4))
#define H_SYNC_WIDTH _H_SYNC_WIDTH(c)
#define _V_SYNC_OFF(x) ((x[10] >> 4) + ((x[11] & 0x0C) << 2))
#define V_SYNC_OFF _V_SYNC_OFF(c)
#define _V_SYNC_WIDTH(x) ((x[10] & 0x0F) + ((x[11] & 0x03) << 4))
#define V_SYNC_WIDTH _V_SYNC_WIDTH(c)
#define _H_SIZE(x) (x[12] + ((x[14] & 0xF0) << 4))
#define H_SIZE _H_SIZE(c)
#define _V_SIZE(x) (x[13] + ((x[14] & 0x0F) << 8))
#define V_SIZE _V_SIZE(c)
#define _H_BORDER(x) (x[15])
#define H_BORDER _H_BORDER(c)
#define _V_BORDER(x) (x[16])
#define V_BORDER _V_BORDER(c)
#define _INTERLACED(x) ((x[17] & 0x80) >> 7)
#define INTERLACED _INTERLACED(c)
#define _STEREO(x) ((x[17] & 0x60) >> 6)
#define STEREO _STEREO(c)
#define _SYNC_T(x) ((x[17] & 0x18) >> 4)
#define SYNC_T _SYNC_T(c)
#define _MISC(x) ((x[17] & 0x06) >> 2)
#define MISC _MISC(c)
#define _MONITOR_DESC_TYPE(x) x[3]
#define MONITOR_DESC_TYPE _MONITOR_DESC_TYPE(c)
#define SERIAL_NUMBER 0xFF
#define ASCII_STR 0xFE
#define MONITOR_RANGES 0xFD
#define _MIN_V(x) x[5]
#define MIN_V _MIN_V(c)
#define _MAX_V(x) x[6]
#define MAX_V _MAX_V(c)
#define _MIN_H(x) x[7]
#define MIN_H _MIN_H(c)
#define _MAX_H(x) x[8]
#define MAX_H _MAX_H(c)
#define _MAX_CLOCK(x) x[9]
#define MAX_CLOCK _MAX_CLOCK(c)
#define MONITOR_NAME 0xFC
#define ADD_COLOR_POINT 0xFB
#define WHITEX F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEX)),2))
#define WHITEY F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEY)),0))
#define _WHITEX_ADD(x,y) F_CC(I_CC(((*(x + y))),(*(x + y + 1)),2))
#define _WHITEY_ADD(x,y) F_CC(I_CC(((*(x + y))),(*(x + y + 2)),0))
#define _WHITE_INDEX1(x) x[5]
#define WHITE_INDEX1 _WHITE_INDEX1(c)
#define _WHITE_INDEX2(x) x[10]
#define WHITE_INDEX2 _WHITE_INDEX2(c)
#define WHITEX1 _WHITEX_ADD(c,6)
#define WHITEY1 _WHITEY_ADD(c,6)
#define WHITEX2 _WHITEX_ADD(c,12)
#define WHITEY2 _WHITEY_ADD(c,12)
#define _WHITE_GAMMA1(x) _GAMMA(x[9])
#define WHITE_GAMMA1 _WHITE_GAMMA1(c)
#define _WHITE_GAMMA2(x) _GAMMA(x[14])
#define WHITE_GAMMA2 _WHITE_GAMMA2(c)
#define ADD_STD_TIMINGS 0xFA
#define _NEXT_DT_MD_SECTION(x) (x = (x + DET_TIMING_INFO_LEN))
#define NEXT_DT_MD_SECTION _NEXT_DT_MD_SECTION(c)
#endif /* _PARSE_EDID_ */
/* input type */
#define DIGITAL(x) x
/* input voltage level */
#define V070 0 /* 0.700V/0.300V */
#define V071 1 /* 0.714V/0.286V */
#define V100 2 /* 1.000V/0.400V */
#define V007 3 /* 0.700V/0.000V */
/* Signal level setup */
#define SIG_SETUP(x) (x)
/* sync characteristics */
#define SEP_SYNC(x) (x & 0x08)
#define COMP_SYNC(x) (x & 0x04)
#define SYNC_O_GREEN(x) (x & 0x02)
#define SYNC_SERR(x) (x & 0x01)
/* DPMS features */
#define DPMS_STANDBY(x) (x & 0x04)
#define DPMS_SUSPEND(x) (x & 0x02)
#define DPMS_OFF(x) (x & 0x01)
/* display type */
#define DISP_MONO 0
#define DISP_RGB 1
#define DISP_MULTCOLOR 2
/* Msc stuff EDID Ver > 1.1 */
#define STD_COLOR_SPACE(x) (x & 0x4)
#define PREFERRED_TIMING_MODE(x) (x & 0x2)
#define GFT_SUPPORTED(x) (x & 0x1)
/* detailed timing misc */
#define IS_INTERLACED(x) (x)
#define IS_STEREO(x) (x)
#define IS_RIGHT_ON_SYNC(x) (x & 0x01)
#define IS_LEFT_ON_SYNC(x) (x & 0x02)
typedef unsigned int Uint;
typedef unsigned char Uchar;
struct vendor {
char name[4];
int prod_id;
Uint serial;
int week;
int year;
};
struct edid_version {
int version;
int revision;
};
struct disp_features {
unsigned int input_type:1;
unsigned int input_voltage:2;
unsigned int input_setup:1;
unsigned int input_sync:5;
int hsize;
int vsize;
float gamma;
unsigned int dpms:3;
unsigned int display_type:2;
unsigned int msc:3;
float redx;
float redy;
float greenx;
float greeny;
float bluex;
float bluey;
float whitex;
float whitey;
};
struct established_timings {
Uchar t1;
Uchar t2;
Uchar t_manu;
};
struct std_timings {
int hsize;
int vsize;
int refresh;
CARD16 id;
};
struct detailed_timings {
int clock;
int h_active;
int h_blanking;
int v_active;
int v_blanking;
int h_sync_off;
int h_sync_width;
int v_sync_off;
int v_sync_width;
int h_size;
int v_size;
int h_border;
int v_border;
unsigned int interlaced:1;
unsigned int stereo:2;
unsigned int sync:2;
unsigned int misc:2;
};
#define DT 0
#define DS_SERIAL 0xFF
#define DS_ASCII_STR 0xFE
#define DS_NAME 0xFC
#define DS_RANGES 0xFD
#define DS_WHITE_P 0xFB
#define DS_STD_TIMINGS 0xFA
struct monitor_ranges {
int min_v;
int max_v;
int min_h;
int max_h;
int max_clock;
};
struct whitePoints{
int index;
float white_x;
float white_y;
float white_gamma;
};
struct detailed_monitor_section {
int type;
union {
struct detailed_timings d_timings;
Uchar serial[13];
Uchar ascii_data[13];
Uchar name[13];
struct monitor_ranges ranges;
struct std_timings std_t[5];
struct whitePoints wp[2];
} section;
};
typedef struct {
int scrnIndex;
struct vendor vendor;
struct edid_version ver;
struct disp_features features;
struct established_timings timings1;
struct std_timings timings2[8];
struct detailed_monitor_section det_mon[4];
xf86vdifPtr vdif;
int no_sections;
Uchar *rawData;
} xf86Monitor, *xf86MonPtr;
extern xf86MonPtr ConfiguredMonitor;
#endif /* _EDID_H_ */
--- NEW FILE: interpret_edid.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/interpret_edid.c,v 1.7 2000/04/17 16:29:55 eich Exp $ */
/* interpret_edid.c: interpret a primary EDID block
*
* Copyright 1998 by Egbert Eich <Egbert.Eich at Physik.TU-Darmstadt.DE>
*/
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
#define _PARSE_EDID_
#include "xf86DDC.h"
static void get_vendor_section(Uchar*, struct vendor *);
static void get_version_section(Uchar*, struct edid_version *);
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 *);
static void get_dt_md_section(Uchar *, struct edid_version *,
struct detailed_monitor_section *det_mon);
static void copy_string(Uchar *, Uchar *);
static void get_dst_timing_section(Uchar *, struct std_timings *);
static void get_monitor_ranges(Uchar *, struct monitor_ranges *);
static void get_whitepoint_section(Uchar *, struct whitePoints *);
static void get_detailed_timing_section(Uchar*, struct detailed_timings *);
xf86MonPtr
xf86InterpretEDID(int scrnIndex, Uchar *block)
{
xf86MonPtr m;
if (!block) return NULL;
if (! (m = xnfcalloc(sizeof(xf86Monitor),1))) return NULL;
m->scrnIndex = scrnIndex;
m->rawData = block;
get_vendor_section(SECTION(VENDOR_SECTION,block),&m->vendor);
get_version_section(SECTION(VERSION_SECTION,block),&m->ver);
get_display_section(SECTION(DISPLAY_SECTION,block),&m->features);
get_established_timing_section(SECTION(ESTABLISHED_TIMING_SECTION,block),
&m->timings1);
get_std_timing_section(SECTION(STD_TIMING_SECTION,block),m->timings2);
get_dt_md_section(SECTION(DET_TIMING_SECTION,block),&m->ver, m->det_mon);
m->no_sections = (int)*(char *)SECTION(NO_EDID,block);
return (m);
}
static void
get_vendor_section(Uchar *c, struct vendor *r)
{
r->name[0] = L1;
r->name[1] = L2;
r->name[2] = L3;
r->name[3] = '\0';
r->prod_id = PROD_ID;
r->serial = SERIAL_NO;
r->week = WEEK;
r->year = YEAR;
}
static void
get_version_section(Uchar *c, struct edid_version *r)
{
r->version = VERSION;
r->revision = REVISION;
}
static void
get_display_section(Uchar *c, struct disp_features *r)
{
r->input_type = INPUT_TYPE;
r->input_voltage = INPUT_VOLTAGE;
r->input_setup = SETUP;
r->input_sync = SYNC;
r->hsize = HSIZE_MAX;
r->vsize = VSIZE_MAX;
r->gamma = GAMMA;
r->dpms = DPMS;
r->display_type = DISPLAY_TYPE;
r->msc = MSC;
r->redx = REDX;
r->redy = REDY;
r->greenx = GREENX;
r->greeny = GREENY;
r->bluex = BLUEX;
r->bluey = BLUEY;
r->whitex = WHITEX;
r->whitey = WHITEY;
}
static void
get_established_timing_section(Uchar *c, struct established_timings *r)
{
r->t1 = T1;
r->t2 = T2;
r->t_manu = T_MANU;
}
static void
get_std_timing_section(Uchar *c, struct std_timings *r)
{
int i;
for (i=0;i<STD_TIMINGS;i++){
r[i].hsize = HSIZE1;
VSIZE1(r[i].vsize);
r[i].refresh = REFRESH_R;
r[i].id = STD_TIMING_ID;
NEXT_STD_TIMING;
}
}
static void
get_dt_md_section(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[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);
break;
}
} else {
det_mon[i].type = DT;
get_detailed_timing_section(c,&det_mon[i].section.d_timings);
}
NEXT_DT_MD_SECTION;
}
}
static void
copy_string(Uchar *c, Uchar *s)
{
int i;
c = c + 5;
for (i = 0; (i < 13 && *c != 0x0A); i++)
*(s++) = *(c++);
*s = 0;
while (i-- && (*--s == 0x20)) *s = 0;
}
static void
get_dst_timing_section(Uchar *c, struct std_timings *t)
{
int j;
c = c + 5;
for (j = 0; j < 5; j++) {
t[j].hsize = HSIZE1;
VSIZE1(t[j].vsize);
t[j].refresh = REFRESH_R;
t[j].id = STD_TIMING_ID;
NEXT_STD_TIMING;
}
}
static void
get_monitor_ranges(Uchar *c, struct monitor_ranges *r)
{
r->min_v = MIN_V;
r->max_v = MAX_V;
r->min_h = MIN_H;
r->max_h = MAX_H;
r->max_clock = MAX_CLOCK * 10;
}
static void
get_whitepoint_section(Uchar *c, struct whitePoints *wp)
{
wp[1].white_x = WHITEX1;
wp[1].white_y = WHITEY1;
wp[2].white_x = WHITEX2;
wp[2].white_y = WHITEY2;
wp[1].index = WHITE_INDEX1;
wp[2].index = WHITE_INDEX2;
wp[1].white_gamma = WHITE_GAMMA1;
wp[2].white_gamma = WHITE_GAMMA2;
}
static void
get_detailed_timing_section(Uchar *c, struct detailed_timings *r)
{
r->clock = PIXEL_CLOCK;
r->h_active = H_ACTIVE;
r->h_blanking = H_BLANK;
r->v_active = V_ACTIVE;
r->v_blanking = V_BLANK;
r->h_sync_off = H_SYNC_OFF;
r->h_sync_width = H_SYNC_WIDTH;
r->v_sync_off = V_SYNC_OFF;
r->v_sync_width = V_SYNC_WIDTH;
r->h_size = H_SIZE;
r->v_size = V_SIZE;
r->h_border = H_BORDER;
r->v_border = V_BORDER;
r->interlaced = INTERLACED;
r->stereo = STEREO;
r->sync = SYNC_T;
r->misc = MISC;
}
--- NEW FILE: interpret_vdif.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/interpret_vdif.c,v 1.5 1999/12/03 19:17:26 eich Exp $ */
#include <X11/Xarch.h>
#include "xf86DDC.h"
#include "vdif.h"
static xf86VdifLimitsPtr* get_limits(CARD8 *c);
static xf86VdifGammaPtr* get_gamma(CARD8 *c);
static xf86VdifTimingPtr* get_timings(CARD8 *c);
#if X_BYTE_ORDER == X_BIG_ENDIAN
static CARD32 swap_byte_order(CARD32 c);
#endif
xf86vdifPtr
xf86InterpretVdif(CARD8 *c)
{
xf86VdifPtr p = (xf86VdifPtr)c;
xf86vdifPtr vdif;
int i;
#if X_BYTE_ORDER == X_BIG_ENDIAN
int length;
#endif
unsigned long l = 0;
if (c == NULL) return NULL;
#if X_BYTE_ORDER == X_BIG_ENDIAN
length = swap_byte_order(p->FileLength);
for (i = 0; i < (length >>2); i++)
((CARD32*)c)[i] = swap_byte_order(((CARD32*)c)[i]) ;
#endif
if (p->VDIFId[0] != 'V' || p->VDIFId[1] != 'D' || p->VDIFId[2] != 'I'
|| p->VDIFId[3] != 'F') return NULL;
for ( i = 12; i < p->FileLength; i++)
l += c[i];
if ( l != p->Checksum) return NULL;
vdif = xalloc(sizeof(xf86vdif));
vdif->vdif = p;
vdif->limits = get_limits(c);
vdif->timings = get_timings(c);
vdif->gamma = get_gamma(c);
vdif->strings = VDIF_STRING(((xf86VdifPtr)c),0);
xfree(c);
return vdif;
}
static xf86VdifLimitsPtr*
get_limits(CARD8 *c)
{
int num, i, j;
xf86VdifLimitsPtr *pp;
xf86VdifLimitsPtr p;
num = ((xf86VdifPtr)c)->NumberOperationalLimits;
pp = xalloc(sizeof(xf86VdifLimitsPtr) * (num+1));
p = VDIF_OPERATIONAL_LIMITS(((xf86VdifPtr)c));
j = 0;
for ( i = 0; i<num; i++) {
if (p->Header.ScnTag == VDIF_OPERATIONAL_LIMITS_TAG)
pp[j++] = p;
VDIF_NEXT_OPERATIONAL_LIMITS(p);
}
pp[j] = NULL;
return pp;
}
static xf86VdifGammaPtr*
get_gamma(CARD8 *c)
{
int num, i, j;
xf86VdifGammaPtr *pp;
xf86VdifGammaPtr p;
num = ((xf86VdifPtr)c)->NumberOptions;
pp = xalloc(sizeof(xf86VdifGammaPtr) * (num+1));
p = (xf86VdifGammaPtr)VDIF_OPTIONS(((xf86VdifPtr)c));
j = 0;
for ( i = 0; i<num; i++)
{
if (p->Header.ScnTag == VDIF_GAMMA_TABLE_TAG)
pp[j++] = p;
VDIF_NEXT_OPTIONS(p);
}
pp[j] = NULL;
return pp;
}
static xf86VdifTimingPtr*
get_timings(CARD8 *c)
{
int num, num_limits;
int i,j,k;
xf86VdifLimitsPtr lp;
xf86VdifTimingPtr *pp;
xf86VdifTimingPtr p;
num = ((xf86VdifPtr)c)->NumberOperationalLimits;
lp = VDIF_OPERATIONAL_LIMITS(((xf86VdifPtr)c));
num_limits = 0;
for (i = 0; i < num; i++) {
if (lp->Header.ScnTag == VDIF_OPERATIONAL_LIMITS_TAG)
num_limits += lp->NumberPreadjustedTimings;
VDIF_NEXT_OPERATIONAL_LIMITS(lp);
}
pp = xalloc(sizeof(xf86VdifTimingPtr)
* (num_limits+1));
j = 0;
lp = VDIF_OPERATIONAL_LIMITS(((xf86VdifPtr) c));
for (i = 0; i < num; i++) {
p = VDIF_PREADJUSTED_TIMING(lp);
for (k = 0; k < lp->NumberPreadjustedTimings; k++) {
if (p->Header.ScnTag == VDIF_PREADJUSTED_TIMING_TAG)
pp[j++] = p;
VDIF_NEXT_PREADJUSTED_TIMING(p);
}
VDIF_NEXT_OPERATIONAL_LIMITS(lp);
}
pp[j] = NULL;
return pp;
}
#if X_BYTE_ORDER == X_BIG_ENDIAN
static CARD32
swap_byte_order(CARD32 c)
{
return ((c & 0xFF000000) >> 24) | ((c & 0xFF0000) >> 8)
| ((c & 0xFF00) << 8) | ((c & 0xFF) << 24);
}
#endif
--- NEW FILE: print_edid.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/print_edid.c,v 1.15 2001/05/22 17:01:23 tsi Exp $ */
/* print_edid.c: print out all information retrieved from display device
*
* Copyright 1998 by Egbert Eich <Egbert.Eich at Physik.TU-Darmstadt.DE>
*/
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
#include "xf86DDC.h"
static void print_vendor(int scrnIndex, struct vendor *);
static void print_version(int scrnIndex, struct edid_version *);
static void print_display(int scrnIndex, struct disp_features *);
static void print_established_timings(int scrnIndex,
struct established_timings *);
static void print_std_timings(int scrnIndex, struct std_timings *);
static void print_detailed_monitor_section(int scrnIndex,
struct detailed_monitor_section *);
static void print_detailed_timings(int scrnIndex, struct detailed_timings *);
static void print_input_features(int scrnIndex, struct disp_features *);
static void print_dpms_features(int scrnIndex, struct disp_features *);
static void print_whitepoint(int scrnIndex, struct disp_features *);
xf86MonPtr
xf86PrintEDID(xf86MonPtr m)
{
if (!(m)) return NULL;
print_vendor(m->scrnIndex,&m->vendor);
print_version(m->scrnIndex,&m->ver);
print_display(m->scrnIndex,&m->features);
print_established_timings(m->scrnIndex,&m->timings1);
print_std_timings(m->scrnIndex,m->timings2);
print_detailed_monitor_section(m->scrnIndex,m->det_mon);
return m;
}
static void
print_vendor(int scrnIndex, struct vendor *c)
{
xf86DrvMsg(scrnIndex, X_INFO, "Manufacturer: %s Model: %x Serial#: %u\n",
(char *)&c->name, c->prod_id, c->serial);
xf86DrvMsg(scrnIndex, X_INFO, "Year: %u Week: %u\n", c->year, c->week);
}
static void
print_version(int scrnIndex, struct edid_version *c)
{
xf86DrvMsg(scrnIndex,X_INFO,"EDID Version: %u.%u\n",c->version,
c->revision);
}
static void
print_display(int scrnIndex, struct disp_features *disp)
{
print_input_features(scrnIndex,disp);
xf86DrvMsg(scrnIndex,X_INFO,"Max H-Image Size [cm]: ");
if (disp->hsize)
xf86ErrorF("horiz.: %i ",disp->hsize);
else
xf86ErrorF("H-Size may change, ");
if (disp->vsize)
xf86ErrorF("vert.: %i\n",disp->vsize);
else
xf86ErrorF("V-Size may change\n");
xf86DrvMsg(scrnIndex,X_INFO,"Gamma: %.2f\n", disp->gamma);
print_dpms_features(scrnIndex,disp);
print_whitepoint(scrnIndex,disp);
}
static void
print_input_features(int scrnIndex, struct disp_features *c)
{
if (DIGITAL(c->input_type))
xf86DrvMsg(scrnIndex,X_INFO,"Digital Display Input\n");
else {
xf86DrvMsg(scrnIndex,X_INFO,"Analog Display Input, ");
xf86ErrorF("Input Voltage Level: ");
switch (c->input_voltage){
case V070:
xf86ErrorF("0.700/0.300 V\n");
break;
case V071:
xf86ErrorF("0.714/0.286 V\n");
break;
case V100:
xf86ErrorF("1.000/0.400 V\n");
break;
case V007:
xf86ErrorF("0.700/0.700 V\n");
break;
default:
xf86ErrorF("undefined\n");
}
if (SIG_SETUP(c->input_setup))
xf86DrvMsg(scrnIndex,X_INFO,"Signal levels configurable\n");
xf86DrvMsg(scrnIndex,X_INFO,"Sync:");
if (SEP_SYNC(c->input_sync))
xf86ErrorF(" Separate");
if (COMP_SYNC(c->input_sync))
xf86ErrorF(" Composite");
if (SYNC_O_GREEN(c->input_sync))
xf86ErrorF(" SyncOnGreen");
if (SYNC_SERR(c->input_sync))
xf86ErrorF("Serration on. "
"V.Sync Pulse req. if CompSync or SyncOnGreen\n");
else xf86ErrorF("\n");
}
}
static void
print_dpms_features(int scrnIndex, struct disp_features *c)
{
if (c->dpms) {
xf86DrvMsg(scrnIndex,X_INFO,"DPMS capabilities:");
if (DPMS_STANDBY(c->dpms)) xf86ErrorF(" StandBy");
if (DPMS_SUSPEND(c->dpms)) xf86ErrorF(" Suspend");
if (DPMS_OFF(c->dpms)) xf86ErrorF(" Off");
} else
xf86DrvMsg(scrnIndex,X_INFO,"No DPMS capabilities specified");
switch (c->display_type){
case DISP_MONO:
xf86ErrorF("; Monochorome/GrayScale Display\n");
break;
case DISP_RGB:
xf86ErrorF("; RGB/Color Display\n");
break;
case DISP_MULTCOLOR:
xf86ErrorF("; Non RGB Multicolor Display\n");
break;
default:
xf86ErrorF("\n");
break;
}
if (STD_COLOR_SPACE(c->msc))
xf86DrvMsg(scrnIndex,X_INFO,
"Default color space is primary color space\n");
if (PREFERRED_TIMING_MODE(c->msc))
xf86DrvMsg(scrnIndex,X_INFO,
"First detailed timing is preferred mode\n");
if (GFT_SUPPORTED(c->msc))
xf86DrvMsg(scrnIndex,X_INFO,
"GTF timings supported\n");
}
static void
print_whitepoint(int scrnIndex, struct disp_features *disp)
{
xf86DrvMsg(scrnIndex,X_INFO,"redX: %.3f redY: %.3f ",
disp->redx,disp->redy);
xf86ErrorF("greenX: %.3f greenY: %.3f\n",
disp->greenx,disp->greeny);
xf86DrvMsg(scrnIndex,X_INFO,"blueX: %.3f blueY: %.3f ",
disp->bluex,disp->bluey);
xf86ErrorF("whiteX: %.3f whiteY: %.3f\n",
disp->whitex,disp->whitey);
}
static void
print_established_timings(int scrnIndex, struct established_timings *t)
{
unsigned char c;
if (t->t1 || t->t2 || t->t_manu)
xf86DrvMsg(scrnIndex,X_INFO,"Supported VESA Video Modes:\n");
c=t->t1;
if (c&0x80) xf86DrvMsg(scrnIndex,X_INFO,"720x400 at 70Hz\n");
if (c&0x40) xf86DrvMsg(scrnIndex,X_INFO,"720x400 at 88Hz\n");
if (c&0x20) xf86DrvMsg(scrnIndex,X_INFO,"640x480 at 60Hz\n");
if (c&0x10) xf86DrvMsg(scrnIndex,X_INFO,"640x480 at 67Hz\n");
if (c&0x08) xf86DrvMsg(scrnIndex,X_INFO,"640x480 at 72Hz\n");
if (c&0x04) xf86DrvMsg(scrnIndex,X_INFO,"640x480 at 75Hz\n");
if (c&0x02) xf86DrvMsg(scrnIndex,X_INFO,"800x600 at 56Hz\n");
if (c&0x01) xf86DrvMsg(scrnIndex,X_INFO,"800x600 at 60Hz\n");
c=t->t2;
if (c&0x80) xf86DrvMsg(scrnIndex,X_INFO,"800x600 at 72Hz\n");
if (c&0x40) xf86DrvMsg(scrnIndex,X_INFO,"800x600 at 75Hz\n");
if (c&0x20) xf86DrvMsg(scrnIndex,X_INFO,"832x624 at 75Hz\n");
if (c&0x10) xf86DrvMsg(scrnIndex,X_INFO,"1024x768 at 87Hz (interlaced)\n");
if (c&0x08) xf86DrvMsg(scrnIndex,X_INFO,"1024x768 at 60Hz\n");
if (c&0x04) xf86DrvMsg(scrnIndex,X_INFO,"1024x768 at 70Hz\n");
if (c&0x02) xf86DrvMsg(scrnIndex,X_INFO,"1024x768 at 75Hz\n");
if (c&0x01) xf86DrvMsg(scrnIndex,X_INFO,"1280x1024 at 75Hz\n");
c=t->t_manu;
if (c&0x80) xf86DrvMsg(scrnIndex,X_INFO,"1152x870 at 75Hz\n");
xf86DrvMsg(scrnIndex,X_INFO,"Manufacturer's mask: %X\n",c&0x7F);
}
static void
print_std_timings(int scrnIndex, struct std_timings *t)
{
int i;
char done = 0;
for (i=0;i<STD_TIMINGS;i++) {
if (t[i].hsize > 256) { /* sanity check */
if (!done) {
xf86DrvMsg(scrnIndex,X_INFO,"Supported Future Video Modes:\n");
done = 1;
}
xf86DrvMsg(scrnIndex,X_INFO,
"#%i: hsize: %i vsize %i refresh: %i vid: %i\n",
i, t[i].hsize, t[i].vsize, t[i].refresh, t[i].id);
}
}
}
static void
print_detailed_monitor_section(int scrnIndex,
struct detailed_monitor_section *m)
{
int i,j;
for (i=0;i<DET_TIMINGS;i++) {
switch (m[i].type) {
case DT:
print_detailed_timings(scrnIndex,&m[i].section.d_timings);
break;
case DS_SERIAL:
xf86DrvMsg(scrnIndex,X_INFO,"Serial No: %s\n",m[i].section.serial);
break;
case DS_ASCII_STR:
xf86DrvMsg(scrnIndex,X_INFO," %s\n",m[i].section.ascii_data);
break;
case DS_NAME:
xf86DrvMsg(scrnIndex,X_INFO,"Monitor name: %s\n",m[i].section.name);
break;
case DS_RANGES:
xf86DrvMsg(scrnIndex,X_INFO,
"Ranges: V min: %i V max: %i Hz, H min: %i H max: %i kHz,",
m[i].section.ranges.min_v, m[i].section.ranges.max_v,
m[i].section.ranges.min_h, m[i].section.ranges.max_h);
if (m[i].section.ranges.max_clock != 0)
xf86ErrorF(" PixClock max %i MHz\n",m[i].section.ranges.max_clock);
else
xf86DrvMsg(scrnIndex,X_INFO,"\n");
break;
case DS_STD_TIMINGS:
for (j = 0; j<5; j++)
xf86DrvMsg(scrnIndex,X_INFO,"#%i: hsize: %i vsize %i refresh: %i "
"vid: %i\n",i,m[i].section.std_t[i].hsize,
m[i].section.std_t[j].vsize,m[i].section.std_t[j].refresh,
m[i].section.std_t[j].id);
break;
case DS_WHITE_P:
for (j = 0; j<2; j++)
if (m[i].section.wp[j].index != 0)
xf86DrvMsg(scrnIndex,X_INFO,
"White point %i: whiteX: %f, whiteY: %f; gamma: %f\n",
m[i].section.wp[j].index,m[i].section.wp[j].white_x,
m[i].section.wp[j].white_y,
m[i].section.wp[j].white_gamma);
break;
}
}
}
static void
print_detailed_timings(int scrnIndex, struct detailed_timings *t)
{
if (t->clock > 15000000) { /* sanity check */
xf86DrvMsg(scrnIndex,X_INFO,"Supported additional Video Mode:\n");
xf86DrvMsg(scrnIndex,X_INFO,"clock: %.1f MHz ",t->clock/1000000.0);
xf86ErrorF("Image Size: %i x %i mm\n",t->h_size,t->v_size);
xf86DrvMsg(scrnIndex,X_INFO,
"h_active: %i h_sync: %i h_sync_end %i h_blank_end %i ",
t->h_active, t->h_sync_off + t->h_active,
t->h_sync_off + t->h_sync_width + t->h_active,
t->h_active + t->h_blanking);
xf86ErrorF("h_border: %i\n",t->h_border);
xf86DrvMsg(scrnIndex,X_INFO,
"v_active: %i v_sync: %i v_sync_end %i v_blanking: %i ",
t->v_active, t->v_sync_off + t->v_active,
t->v_sync_off + t->v_sync_width + t->v_active,
t->v_active + t->v_blanking);
xf86ErrorF("v_border: %i\n",t->v_border);
if (IS_STEREO(t->stereo)) {
xf86DrvMsg(scrnIndex,X_INFO,"Stereo: ");
if (IS_RIGHT_ON_SYNC(t->stereo))
xf86ErrorF("right channel on sync\n");
else xf86ErrorF("right channel on sync\n");
}
}
}
--- NEW FILE: print_vdif.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/print_vdif.c,v 1.4tsi Exp $ */
#include "vdif.h"
#include "misc.h"
#include "xf86DDC.h"
static void print_vdif(xf86VdifPtr l, char *s);
static void print_timings(xf86VdifTimingPtr *pt);
static void print_limits(xf86VdifLimitsPtr *pl);
static void print_gamma(xf86VdifGammaPtr *pg);
static void print_type(CARD8 c);
static void print_polarity(CARD8 c);
void
xf86print_vdif(xf86vdifPtr v)
{
print_vdif(v->vdif,v->strings);
print_limits(v->limits);
print_timings(v->timings);
print_gamma(v->gamma);
}
static void
print_vdif(xf86VdifPtr l, char *s)
{
ErrorF("Version %i.%i",l->VDIFVersion,l->VDIFRevision);
ErrorF(" Date: %i/%i/%i, Manufactured: %i/%i/%i\n",l->Date[0],
l->Date[1],l->Date[2],l->DateManufactured[0],
l->DateManufactured[1],l->DateManufactured[2]);
ErrorF("File Revision: %i",l->FileRevision);
ErrorF("Manufacturer: %s\n",s + l->Manufacturer);
ErrorF("ModelNumber: %s\n",s + l->ModelNumber);
ErrorF("VDIFIndex: %s\n",s +l->MinVDIFIndex);
ErrorF("Version: %s\n",s + l->Version);
ErrorF("SerialNumber %s\n",s + l->SerialNumber);
ErrorF("MonitorType: ");
switch (l->MonitorType) {
case VDIF_MONITOR_MONOCHROME:
ErrorF("Mono\n");
break;
case VDIF_MONITOR_COLOR:
ErrorF("Color\n");
break;
}
ErrorF("CRT Size: %i inches\n",l->CRTSize);
switch (l->MonitorType) {
case VDIF_MONITOR_MONOCHROME:
ErrorF("Border: %i percent\n",
l->BorderRed);
ErrorF("Phosphor Decay: 1: %i,",l->RedPhosphorDecay);
if (l->GreenPhosphorDecay !=0)
ErrorF(" 2: %i,",l->GreenPhosphorDecay);
if (l->BluePhosphorDecay !=0)
ErrorF(" 3: %i",l->BluePhosphorDecay);
ErrorF(" ms\n");
if (l->RedChromaticity_x)
ErrorF("Chromaticity: 1: x:%f, y:%f; ",
l->RedChromaticity_x/1000.0,l->RedChromaticity_y/1000.0);
if (l->GreenChromaticity_x)
ErrorF("Chromaticity: 2: x:%f, y:%f; ",
l->GreenChromaticity_x/1000.0,l->GreenChromaticity_y/1000.0);
if (l->BlueChromaticity_x)
ErrorF("Chromaticity: 3: x:%f, y:%f ",
l->BlueChromaticity_x/1000.0,l->BlueChromaticity_y/1000.0);
ErrorF("\n");
ErrorF("Gamma: %f\n",l->RedGamma/1000.0);
break;
case VDIF_MONITOR_COLOR:
ErrorF("Border: Red: %i Green: %i Blue: %i percent\n",
l->BorderRed,l->BorderGreen,l->BorderBlue);
ErrorF("Phosphor Decay: Red: %i, Green: %i, Blue: %i ms\n",
l->RedPhosphorDecay,l->GreenPhosphorDecay,l->BluePhosphorDecay);
ErrorF("Chromaticity: Red: x:%f, y:%f; Green: x:%f, y:%f; "
"Blue: x:%f, y:%f\n",
l->RedChromaticity_x/1000.0,l->RedChromaticity_y/1000.0,
l->GreenChromaticity_x/1000.0,l->GreenChromaticity_y/1000.0,
l->BlueChromaticity_x/1000.0,l->BlueChromaticity_y/1000.0);
ErrorF("Gamma: Red:%f, Green:%f, Blue:%f\n",l->RedGamma/1000.0,
l->GreenGamma/1000.0,l->BlueGamma/1000.0);
break;
}
ErrorF("White Point: x: %f y: %f Y: %f\n",l->WhitePoint_x/1000.0,
l->WhitePoint_y/1000.0,l->WhitePoint_Y/1000.0);
}
static void
print_limits(xf86VdifLimitsPtr *pl)
{
int i = 0;
xf86VdifLimitsPtr l;
while((l = pl[i]) != NULL) {
ErrorF("Max display resolution: %i x %i pixel\n",l->MaxHorPixel,
l->MaxVerPixel);
ErrorF("Size of active area: %i x %i millimeters\n",l->MaxHorActiveLength,
l->MaxVerActiveHeight);
ErrorF("Video Type: ");
print_type(l->VideoType);
ErrorF("Sync Type: ");
print_type(l->SyncType);
ErrorF("Sync Configuration ");
switch (l->SyncConfiguration) {
case VDIF_SYNC_SEPARATE:
ErrorF("separate\n");
break;
case VDIF_SYNC_C:
ErrorF("composite C\n");
break;
case VDIF_SYNC_CP:
ErrorF("composite CP\n");
break;
case VDIF_SYNC_G:
ErrorF("composite G\n");
break;
case VDIF_SYNC_GP:
ErrorF("composite GP\n");
break;
case VDIF_SYNC_OTHER:
ErrorF("other\n");
break;
}
ErrorF("Termination Resistance: %i\n",l->TerminationResistance);
ErrorF("Levels: white: %i, black: %i, blank: %i, sync: %i mV\n",
l->WhiteLevel,l->BlackLevel,l->BlankLevel,l->SyncLevel);
ErrorF("Max. Pixel Clock: %f MHz\n",l->MaxPixelClock/1000.0);
ErrorF("Freq. Range: Hor.: %f - %f kHz, Ver.: %f - %f Hz\n",
l->MaxHorFrequency/1000.0,l->MinHorFrequency/1000.0,
l->MaxVerFrequency/1000.0,l->MinVerFrequency/1000.0);
ErrorF("Retrace time: Hor: %f us, Ver: %f ms\n",l->MinHorRetrace/1000.0,
l->MinVerRetrace/1000.0);
}
}
static void
print_timings(xf86VdifTimingPtr *pt)
{
int i = 0;
xf86VdifTimingPtr t;
while((t = pt[i]) != NULL) {
ErrorF("SVGA / SVPMI mode number: %i\n",t->PreadjustedTimingName);
ErrorF("Mode %i x %i\n",t->HorPixel,t->VerPixel);
ErrorF("Size: %i x %i mm\n",t->HorAddrLength,t->VerAddrHeight);
ErrorF("Ratios: %i/%i\n",t->PixelWidthRatio,t->PixelHeightRatio);
ErrorF("Character width: %i",t->CharacterWidth);
ErrorF("Clock: %f MHz HFreq.: %f kHz, VFreq: %f Hz\n",t->PixelClock/1000.0,
t->HorFrequency/1000.0,t->VerFrequency/1000.0);
ErrorF("Htotal: %f us, Vtotal %f ms\n", t->HorTotalTime/1000.0,
t->VerTotalTime/1000.0);
ErrorF("HDisp: %f, HBlankStart: %f, HBlankLength: %f, "
"HSyncStart: %f HSyncEnd: %f us\n",t->HorAddrTime/1000.0,
t->HorBlankStart/1000.0,t->HorBlankTime/1000.0,
t->HorSyncStart/1000.0,t->HorSyncTime/1000.0);
ErrorF("VDisp: %f, VBlankStart: %f, VBlankLength: %f, "
"VSyncStart: %f VSyncEnd: %f us\n",t->VerAddrTime/1000.0,
t->VerBlankStart/1000.0,t->VerBlankTime/1000.0,
t->VerSyncStart/1000.0,t->VerSyncTime/1000.0);
ErrorF("Scan Type: ");
switch (t->ScanType) {
case VDIF_SCAN_INTERLACED:
ErrorF("interlaced ");
break;
case VDIF_SCAN_NONINTERLACED:
ErrorF("non interlaced ");
break;
case VDIF_SCAN_OTHER:
ErrorF("other ");
break;
}
ErrorF("Polarity: H: ");
print_polarity(t->HorSyncPolarity);
ErrorF("V: ");
print_polarity(t->VerSyncPolarity);
ErrorF("\n");
}
}
static void
print_gamma(xf86VdifGammaPtr *pg)
{
int i = 0;
xf86VdifGammaPtr g;
while((g = pg[i]) != NULL) {
ErrorF("Gamma Table Entries: %i\n",g->GammaTableEntries);
}
}
static void
print_type(CARD8 c)
{
switch (c) {
case VDIF_VIDEO_TTL :
ErrorF("TTL\n");
break;
case VDIF_VIDEO_ANALOG :
ErrorF("Analog\n");
break;
case VDIF_VIDEO_ECL:
ErrorF("ECL\n");
break;
case VDIF_VIDEO_DECL:
ErrorF("DECL\n");
break;
case VDIF_VIDEO_OTHER:
ErrorF("other\n");
break;
}
}
static void
print_polarity(CARD8 c)
{
switch (c) {
case VDIF_POLARITY_NEGATIVE:
ErrorF(" Neg.");
break;
case VDIF_POLARITY_POSITIVE:
ErrorF(" Pos.");
break;
}
}
--- NEW FILE: vdif.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/vdif.h,v 1.4tsi Exp $ */
#ifndef _VDIF_H
#define _VDIF_H
#define VDIF_MONITOR_MONOCHROME 0
#define VDIF_MONITOR_COLOR 1
#define VDIF_VIDEO_TTL 0
#define VDIF_VIDEO_ANALOG 1
#define VDIF_VIDEO_ECL 2
#define VDIF_VIDEO_DECL 3
#define VDIF_VIDEO_OTHER 4
#define VDIF_SYNC_SEPARATE 0
#define VDIF_SYNC_C 1
#define VDIF_SYNC_CP 2
#define VDIF_SYNC_G 3
#define VDIF_SYNC_GP 4
#define VDIF_SYNC_OTHER 5
#define VDIF_SCAN_NONINTERLACED 0
#define VDIF_SCAN_INTERLACED 1
#define VDIF_SCAN_OTHER 2
#define VDIF_POLARITY_NEGATIVE 0
#define VDIF_POLARITY_POSITIVE 1
#include <X11/Xmd.h>
#undef CARD32
#define CARD32 unsigned int /* ... on all supported platforms */
typedef struct _VDIF { /* Monitor Description: */
CARD8 VDIFId[4]; /* alway "VDIF" */
CARD32 FileLength; /* lenght of the whole file */
CARD32 Checksum; /* sum of all bytes in the file after*/
/* this field */
CARD16 VDIFVersion; /* structure version number */
CARD16 VDIFRevision; /* structure revision number */
CARD16 Date[3]; /* file date Year/Month/Day */
CARD16 DateManufactured[3]; /* date Year/Month/Day */
CARD32 FileRevision; /* file revision string */
CARD32 Manufacturer; /* ASCII ID of the manufacturer */
CARD32 ModelNumber; /* ASCII ID of the model */
CARD32 MinVDIFIndex; /* ASCII ID of Minimum VDIF index */
CARD32 Version; /* ASCII ID of the model version */
CARD32 SerialNumber; /* ASCII ID of the serial number */
CARD8 MonitorType; /* Monochrome or Color */
CARD8 CRTSize; /* inches */
CARD8 BorderRed; /* percent */
CARD8 BorderGreen; /* percent */
CARD8 BorderBlue; /* percent */
CARD8 Reserved1; /* padding */
CARD16 Reserved2; /* padding */
CARD32 RedPhosphorDecay; /* microseconds */
CARD32 GreenPhosphorDecay; /* microseconds */
CARD32 BluePhosphorDecay; /* microseconds */
CARD16 WhitePoint_x; /* WhitePoint in CIExyY (scale 1000) */
CARD16 WhitePoint_y;
CARD16 WhitePoint_Y;
CARD16 RedChromaticity_x; /* Red chromaticity in x,y */
CARD16 RedChromaticity_y;
CARD16 GreenChromaticity_x; /* Green chromaticity in x,y */
CARD16 GreenChromaticity_y;
CARD16 BlueChromaticity_x; /* Blue chromaticity in x,y */
CARD16 BlueChromaticity_y;
CARD16 RedGamma; /* Gamme curve exponent (scale 1000) */
CARD16 GreenGamma;
CARD16 BlueGamma;
CARD32 NumberOperationalLimits;
CARD32 OffsetOperationalLimits;
CARD32 NumberOptions; /* optinal sections (gamma table) */
CARD32 OffsetOptions;
CARD32 OffsetStringTable;
} xf86VdifRec, *xf86VdifPtr;
typedef enum { /* Tags for section identification */
VDIF_OPERATIONAL_LIMITS_TAG = 1,
VDIF_PREADJUSTED_TIMING_TAG,
VDIF_GAMMA_TABLE_TAG
} VDIFScnTag;
typedef struct _VDIFScnHdr { /* Generic Section Header: */
CARD32 ScnLength; /* lenght of section */
CARD32 ScnTag; /* tag for section identification */
} VDIFScnHdrRec, *VDIFScnHdrPtr;
typedef struct _VDIFLimits { /* Operational Limits: */
VDIFScnHdrRec Header; /* common section info */
CARD16 MaxHorPixel; /* pixels */
CARD16 MaxVerPixel; /* lines */
CARD16 MaxHorActiveLength; /* millimeters */
CARD16 MaxVerActiveHeight; /* millimeters */
CARD8 VideoType; /* TTL / Analog / ECL / DECL */
CARD8 SyncType; /* TTL / Analog / ECL / DECL */
CARD8 SyncConfiguration; /* separate / composite / other */
CARD8 Reserved1; /* padding */
CARD16 Reserved2; /* padding */
CARD16 TerminationResistance; /* */
CARD16 WhiteLevel; /* millivolts */
CARD16 BlackLevel; /* millivolts */
CARD16 BlankLevel; /* millivolts */
CARD16 SyncLevel; /* millivolts */
CARD32 MaxPixelClock; /* kiloHertz */
CARD32 MinHorFrequency; /* Hertz */
CARD32 MaxHorFrequency; /* Hertz */
CARD32 MinVerFrequency; /* milliHertz */
CARD32 MaxVerFrequency; /* milliHertz */
CARD16 MinHorRetrace; /* nanoseconds */
CARD16 MinVerRetrace; /* microseconds */
CARD32 NumberPreadjustedTimings;
CARD32 OffsetNextLimits;
} xf86VdifLimitsRec, *xf86VdifLimitsPtr;
typedef struct _VDIFTiming { /* Preadjusted Timing: */
VDIFScnHdrRec Header; /* common section info */
CARD32 PreadjustedTimingName; /* SVGA/SVPMI mode number */
CARD16 HorPixel; /* pixels */
CARD16 VerPixel; /* lines */
CARD16 HorAddrLength; /* millimeters */
CARD16 VerAddrHeight; /* millimeters */
CARD8 PixelWidthRatio; /* gives H:V */
CARD8 PixelHeightRatio;
CARD8 Reserved1; /* padding */
CARD8 ScanType; /* noninterlaced / interlaced / other*/
CARD8 HorSyncPolarity; /* negative / positive */
CARD8 VerSyncPolarity; /* negative / positive */
CARD16 CharacterWidth; /* pixels */
CARD32 PixelClock; /* kiloHertz */
CARD32 HorFrequency; /* Hertz */
CARD32 VerFrequency; /* milliHertz */
CARD32 HorTotalTime; /* nanoseconds */
CARD32 VerTotalTime; /* microseconds */
CARD16 HorAddrTime; /* nanoseconds */
CARD16 HorBlankStart; /* nanoseconds */
CARD16 HorBlankTime; /* nanoseconds */
CARD16 HorSyncStart; /* nanoseconds */
CARD16 HorSyncTime; /* nanoseconds */
CARD16 VerAddrTime; /* microseconds */
CARD16 VerBlankStart; /* microseconds */
CARD16 VerBlankTime; /* microseconds */
CARD16 VerSyncStart; /* microseconds */
CARD16 VerSyncTime; /* microseconds */
} xf86VdifTimingRec, *xf86VdifTimingPtr;
typedef struct _VDIFGamma { /* Gamma Table: */
VDIFScnHdrRec Header; /* common section info */
CARD16 GammaTableEntries; /* count of grays or RGB 3-tuples */
CARD16 Unused1;
} xf86VdifGammaRec, *xf86VdifGammaPtr;
/* access macros */
#define VDIF_OPERATIONAL_LIMITS(vdif) \
((xf86VdifLimitsPtr)((char*)(vdif) + (vdif)->OffsetOperationalLimits))
#define VDIF_NEXT_OPERATIONAL_LIMITS(limits) limits = \
((xf86VdifLimitsPtr)((char*)(limits) + (limits)->OffsetNextLimits))
#define VDIF_PREADJUSTED_TIMING(limits) \
((xf86VdifTimingPtr)((char*)(limits) + (limits)->Header.ScnLength))
#define VDIF_NEXT_PREADJUSTED_TIMING(timing) timing = \
((xf86VdifTimingPtr)((char*)(timing) + (timing)->Header.ScnLength))
#define VDIF_OPTIONS(vdif) \
((VDIFScnHdrPtr)((char*)(vdif) + (vdif)->OffsetOptions))
#define VDIF_NEXT_OPTIONS(options) options = \
((xf86VdifGammaPtr)((char*)(options) + (options)->Header.ScnLength))
#define VDIF_STRING(vdif, string) \
((char*)((char*)vdif + vdif->OffsetStringTable + (string)))
typedef struct _vdif {
xf86VdifPtr vdif;
xf86VdifLimitsPtr *limits;
xf86VdifTimingPtr *timings;
xf86VdifGammaPtr *gamma;
char * strings;
} xf86vdif, *xf86vdifPtr;
#undef CARD32
#endif
--- NEW FILE: xf86DDC.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/xf86DDC.c,v 1.26 2003/08/22 17:56:24 dawes Exp $ */
/* xf86DDC.c
*
* Copyright 1998,1999 by Egbert Eich <Egbert.Eich at Physik.TU-Darmstadt.DE>
*/
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
#include "xf86DDC.h"
#include "ddcPriv.h"
#ifdef XFree86LOADER
static const OptionInfoRec *DDCAvailableOptions(void *unused);
#endif
const char *i2cSymbols[] = {
"xf86CreateI2CDevRec",
"xf86I2CDevInit",
"xf86I2CWriteRead",
"xf86I2CFindDev",
"xf86DestroyI2CDevRec",
NULL
};
#ifdef XFree86LOADER
static MODULESETUPPROTO(ddcSetup);
static XF86ModuleVersionInfo ddcVersRec =
{
"ddc",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
1, 0, 0,
ABI_CLASS_VIDEODRV, /* needs the video driver ABI */
ABI_VIDEODRV_VERSION,
MOD_CLASS_NONE,
{0,0,0,0}
};
XF86ModuleData ddcModuleData = { &ddcVersRec, ddcSetup, NULL };
ModuleInfoRec DDC = {
1,
"DDC",
NULL,
0,
DDCAvailableOptions,
};
static pointer
ddcSetup(pointer module, pointer opts, int *errmaj, int *errmin)
{
static Bool setupDone = FALSE;
if (!setupDone) {
setupDone = TRUE;
#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
#endif
xf86AddModuleInfo(&DDC, module);
/*
* Tell the loader about symbols from other modules that this module
* might refer to.
*/
LoaderRefSymLists(i2cSymbols, NULL);
}
/*
* The return value must be non-NULL on success even though there
* is no TearDownProc.
*/
return (pointer)1;
}
#endif
#define RETRIES 4
static unsigned char *EDIDRead_DDC1(
ScrnInfoPtr pScrn,
void (*)(ScrnInfoPtr,xf86ddcSpeed),
unsigned int (*)(ScrnInfoPtr)
);
static Bool TestDDC1(
ScrnInfoPtr pScrn,
unsigned int (*)(ScrnInfoPtr)
);
static unsigned int *FetchEDID_DDC1(
ScrnInfoPtr,
register unsigned int (*)(ScrnInfoPtr)
);
static unsigned char* EDID1Read_DDC2(
int scrnIndex,
I2CBusPtr pBus
);
static unsigned char * VDIFRead(
int scrnIndex,
I2CBusPtr pBus,
int start
);
static unsigned char * DDCRead_DDC2(
int scrnIndex,
I2CBusPtr pBus,
int start,
int len
);
typedef enum {
DDCOPT_NODDC1,
DDCOPT_NODDC2,
DDCOPT_NODDC
} 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 },
{ -1, NULL, OPTV_NONE, {0}, FALSE },
};
#ifdef XFree86LOADER
/*ARGSUSED*/
static const OptionInfoRec *
DDCAvailableOptions(void *unused)
{
return (DDCOptions);
}
#endif
xf86MonPtr
xf86DoEDID_DDC1(
int scrnIndex, void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed),
unsigned int (*DDC1Read)(ScrnInfoPtr)
)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
unsigned char *EDID_block = NULL;
xf86MonPtr tmp = NULL;
int sigio;
/* Default DDC and DDC1 to enabled. */
Bool noddc = FALSE, noddc1 = FALSE;
OptionInfoPtr options;
options = xnfalloc(sizeof(DDCOptions));
(void)memcpy(options, DDCOptions, sizeof(DDCOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
xf86GetOptValBool(options, DDCOPT_NODDC1, &noddc1);
xfree(options);
if (noddc || noddc1)
return NULL;
sigio = xf86BlockSIGIO();
EDID_block = EDIDRead_DDC1(pScrn,DDC1SetSpeed,DDC1Read);
xf86UnblockSIGIO(sigio);
if (EDID_block){
tmp = xf86InterpretEDID(scrnIndex,EDID_block);
}
#ifdef DEBUG
else ErrorF("No EDID block returned\n");
if (!tmp)
ErrorF("Cannot interpret EDID block\n");
#endif
return tmp;
}
xf86MonPtr
xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
unsigned char *EDID_block = NULL;
unsigned char *VDIF_Block = NULL;
xf86MonPtr tmp = NULL;
/* Default DDC and DDC2 to enabled. */
Bool noddc = FALSE, noddc2 = FALSE;
OptionInfoPtr options;
options = xnfalloc(sizeof(DDCOptions));
(void)memcpy(options, DDCOptions, sizeof(DDCOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2);
xfree(options);
if (noddc || noddc2)
return NULL;
EDID_block = EDID1Read_DDC2(scrnIndex,pBus);
if (EDID_block){
tmp = xf86InterpretEDID(scrnIndex,EDID_block);
} else {
#ifdef DEBUG
ErrorF("No EDID block returned\n");
#endif
return NULL;
}
#ifdef DEBUG
if (!tmp)
ErrorF("Cannot interpret EDID block\n");
ErrorF("Sections to follow: %i\n",tmp->no_sections);
#endif
VDIF_Block =
VDIFRead(scrnIndex, pBus, EDID1_LEN * (tmp->no_sections + 1));
tmp->vdif = xf86InterpretVdif(VDIF_Block);
return tmp;
}
/*
* read EDID record , pass it to callback function to interpret.
* callback function will store it for further use by calling
* function; it will also decide if we need to reread it
*/
static unsigned char *
EDIDRead_DDC1(ScrnInfoPtr pScrn, void (*DDCSpeed)(ScrnInfoPtr,xf86ddcSpeed),
unsigned int (*read_DDC)(ScrnInfoPtr))
{
unsigned char *EDID_block = NULL;
int count = RETRIES;
if (!read_DDC) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"chipset doesn't support DDC1\n");
return NULL;
};
if (TestDDC1(pScrn,read_DDC)==-1) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No DDC signal\n");
return NULL;
};
if (DDCSpeed) DDCSpeed(pScrn,DDC_FAST);
do {
EDID_block = GetEDID_DDC1(FetchEDID_DDC1(pScrn,read_DDC));
count --;
} while (!EDID_block && count);
if (DDCSpeed) DDCSpeed(pScrn,DDC_SLOW);
return EDID_block;
}
/* test if DDC1 return 0 if not */
static Bool
TestDDC1(ScrnInfoPtr pScrn, unsigned int (*read_DDC)(ScrnInfoPtr))
{
int old, count;
old = read_DDC(pScrn);
count = HEADER * BITS_PER_BYTE;
do {
/* wait for next retrace */
if (old != read_DDC(pScrn)) break;
} while(count--);
return (count);
}
/* fetch entire EDID record; DDC bit needs to be masked */
static unsigned int *
FetchEDID_DDC1(register ScrnInfoPtr pScrn,
register unsigned int (*read_DDC)(ScrnInfoPtr))
{
int count = NUM;
unsigned int *ptr, *xp;
ptr=xp=xalloc(sizeof(int)*NUM);
if (!ptr) return NULL;
do {
/* wait for next retrace */
*xp = read_DDC(pScrn);
xp++;
} while(--count);
return (ptr);
}
static unsigned char*
EDID1Read_DDC2(int scrnIndex, I2CBusPtr pBus)
{
return DDCRead_DDC2(scrnIndex, pBus, 0, EDID1_LEN);
}
static unsigned char*
VDIFRead(int scrnIndex, I2CBusPtr pBus, int start)
{
unsigned char * Buffer, *v_buffer = NULL, *v_bufferp = NULL;
int i, num = 0;
/* read VDIF length in 64 byte blocks */
Buffer = DDCRead_DDC2(scrnIndex, pBus,start,64);
if (Buffer == NULL)
return NULL;
#ifdef DEBUG
ErrorF("number of 64 bit blocks: %i\n",Buffer[0]);
#endif
if ((num = Buffer[0]) > 0)
v_buffer = v_bufferp = xalloc(sizeof(unsigned char) * 64 * num);
for (i = 0; i < num; i++) {
Buffer = DDCRead_DDC2(scrnIndex, pBus,start,64);
if (Buffer == NULL) {
xfree (v_buffer);
return NULL;
}
memcpy(v_bufferp,Buffer,63); /* 64th byte is checksum */
xfree(Buffer);
v_bufferp += 63;
}
return v_buffer;
}
static unsigned char *
DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len)
{
I2CDevPtr dev;
unsigned char W_Buffer[2];
int w_bytes;
unsigned char *R_Buffer;
int i;
xf86LoaderReqSymLists(i2cSymbols, NULL);
if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) {
dev = xf86CreateI2CDevRec();
dev->DevName = "ddc2";
dev->SlaveAddr = 0xA0;
dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
dev->StartTimeout = 550;
dev->BitTimeout = 40;
dev->ByteTimeout = 40;
dev->AcknTimeout = 40;
dev->pI2CBus = pBus;
if (!xf86I2CDevInit(dev)) {
xf86DrvMsg(scrnIndex, X_PROBED, "No DDC2 device\n");
return NULL;
}
}
if (start < 0x100) {
w_bytes = 1;
W_Buffer[0] = start;
} else {
w_bytes = 2;
W_Buffer[0] = start & 0xFF;
W_Buffer[1] = (start & 0xFF00) >> 8;
}
R_Buffer = xcalloc(1,sizeof(unsigned char)
* (len));
for (i=0; i<RETRIES; i++) {
if (xf86I2CWriteRead(dev, W_Buffer,w_bytes, R_Buffer,len)) {
if (!DDC_checksum(R_Buffer,len))
return R_Buffer;
#ifdef DEBUG
else ErrorF("Checksum error in EDID block\n");
#endif
}
#ifdef DEBUG
else ErrorF("Error reading EDID block\n");
#endif
}
xf86DestroyI2CDevRec(dev,TRUE);
xfree(R_Buffer);
return NULL;
}
--- NEW FILE: xf86DDC.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/xf86DDC.h,v 1.10 2000/06/07 22:03:09 tsi Exp $ */
/* xf86DDC.h
*
* This file contains all information to interpret a standard EDIC block
* transmitted by a display device via DDC (Display Data Channel). So far
* there is no information to deal with optional EDID blocks.
* DDC is a Trademark of VESA (Video Electronics Standard Association).
*
* Copyright 1998 by Egbert Eich <Egbert.Eich at Physik.TU-Darmstadt.DE>
*/
#ifndef XF86_DDC_H
# define XF86_DDC_H
#include "edid.h"
#include "xf86i2c.h"
#include "xf86str.h"
/* speed up / slow down */
typedef enum {
DDC_SLOW,
DDC_FAST
} xf86ddcSpeed;
extern xf86MonPtr xf86DoEDID_DDC1(
int scrnIndex,
void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed),
unsigned int (*DDC1Read)(ScrnInfoPtr)
);
extern xf86MonPtr xf86DoEDID_DDC2(
int scrnIndex,
I2CBusPtr pBus
);
extern xf86MonPtr xf86PrintEDID(
xf86MonPtr monPtr
);
extern xf86MonPtr xf86InterpretEDID(
int screenIndex, Uchar *block
);
extern xf86vdifPtr xf86InterpretVdif(
CARD8 *c
);
extern Bool xf86SetDDCproperties(
ScrnInfoPtr pScreen,
xf86MonPtr DDC
);
extern void xf86print_vdif(
xf86vdifPtr v
);
#endif
- Previous message: xserver/hw/xorg/common Makefile.am, NONE, 1.1 atKeynames.h, NONE,
1.1 compiler.h, NONE, 1.1 fourcc.h, NONE, 1.1 xf86.h, NONE,
1.1 xf86Bus.c, NONE, 1.1 xf86Bus.h, NONE, 1.1 xf86Config.c,
NONE, 1.1 xf86Config.h, NONE, 1.1 xf86Configure.c, NONE,
1.1 xf86Cursor.c, NONE, 1.1 xf86DGA.c, NONE, 1.1 xf86DPMS.c,
NONE, 1.1 xf86Debug.c, NONE, 1.1 xf86DefModes.c, NONE,
1.1 xf86DoProbe.c, NONE, 1.1 xf86DoScanPci.c, NONE,
1.1 xf86Events.c, NONE, 1.1 xf86Globals.c, NONE,
1.1 xf86Helper.c, NONE, 1.1 xf86InPriv.h, NONE, 1.1 xf86Init.c,
NONE, 1.1 xf86Io.c, NONE, 1.1 xf86Kbd.c, NONE,
1.1 xf86KbdBSD.c, NONE, 1.1 xf86KbdLnx.c, NONE,
1.1 xf86KbdMach.c, NONE, 1.1 xf86Keymap.h, NONE,
1.1 xf86MiscExt.c, NONE, 1.1 xf86Mode.c, NONE,
1.1 xf86Module.h, NONE, 1.1 xf86Opt.h, NONE, 1.1 xf86Option.c,
NONE, 1.1 xf86PM.c, NONE, 1.1 xf86PciInfo.h, NONE,
1.1 xf86Priv.h, NONE, 1.1 xf86Privstr.h, NONE, 1.1 xf86RandR.c,
NONE, 1.1 xf86Resources.h, NONE, 1.1 xf86Versions.c, NONE,
1.1 xf86VidMode.c, NONE, 1.1 xf86XKB.c, NONE, 1.1 xf86Xinput.c,
NONE, 1.1 xf86Xinput.h, NONE, 1.1 xf86bigfont.c, NONE,
1.1 xf86cmap.c, NONE, 1.1 xf86cmap.h, NONE, 1.1 xf86dga.c,
NONE, 1.1 xf86dga2.c, NONE, 1.1 xf86dgaext.h, NONE,
1.1 xf86fbBus.c, NONE, 1.1 xf86fbman.c, NONE, 1.1 xf86fbman.h,
NONE, 1.1 xf86isaBus.c, NONE, 1.1 xf86misc.c, NONE,
1.1 xf86miscproc.h, NONE, 1.1 xf86noBus.c, NONE,
1.1 xf86pciBus.c, NONE, 1.1 xf86pciBus.h, NONE,
1.1 xf86sbusBus.c, NONE, 1.1 xf86sbusBus.h, NONE,
1.1 xf86str.h, NONE, 1.1 xf86vmode.c, NONE, 1.1 xf86xv.c, NONE,
1.1 xf86xv.h, NONE, 1.1 xf86xvmc.c, NONE, 1.1 xf86xvmc.h, NONE,
1.1 xf86xvpriv.h, NONE, 1.1 xisb.c, NONE, 1.1 xisb.h, NONE, 1.1
- Next message: xserver/hw/xorg/drivers Imakefile, NONE, 1.1 Makefile.am, NONE,
1.1 confdrv.sh, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the xserver-commit
mailing list