xserver: Branch 'master' - 8 commits

Eric Anholt anholt at kemper.freedesktop.org
Tue Nov 28 21:15:09 EET 2006


 hw/xfree86/ddc/Makefile.am   |    3 
 hw/xfree86/ddc/ddcProperty.c |  292 ---------------------------------
 hw/xfree86/ddc/edid_modes.c  |  348 ++++++++++++++++++++++++++++++++++++++++
 hw/xfree86/ddc/xf86DDC.h     |    2 
 randr/mirandr.c              |    9 -
 randr/randrstr.h             |   57 +++++-
 randr/rrcrtc.c               |    2 
 randr/rrdispatch.c           |   26 +--
 randr/rrmode.c               |    3 
 randr/rroutput.c             |    2 
 randr/rrproperty.c           |  371 ++++++++++++++++++++++++++++++++-----------
 randr/rrsdispatch.c          |   46 +++--
 12 files changed, 744 insertions(+), 417 deletions(-)

New commits:
diff-tree b0c8558b9d9a9984c0067960392e28f5a7622b29 (from 6245e9dd4719c5dc15ff45d49cf626123794038b)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sun Nov 26 19:31:48 2006 -0800

    Ensure RandR resource types are registered before resources are created.
    
    Now that resources can be created during server initialization, make sure
    the crtc, output and mode resource types are created before attempting to
    create associated resources.
    (cherry picked from commit ec83d674167e7045d5317b179c9998e3172a26dc)

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index b81c390..212352c 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -55,6 +55,8 @@ RRCrtcCreate (void	*devPrivate)
 {
     RRCrtcPtr	crtc;
     
+    if (!RRInit())
+	return NULL;
     crtc = xalloc (sizeof (RRCrtcRec));
     if (!crtc)
 	return NULL;
diff --git a/randr/rrmode.c b/randr/rrmode.c
index 3cd9ef2..a0696e1 100644
--- a/randr/rrmode.c
+++ b/randr/rrmode.c
@@ -67,6 +67,9 @@ RRModeGet (xRRModeInfo	*modeInfo,
 	}
     }
 
+    if (!RRInit ())
+	return NULL;
+
     mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1);
     if (!mode)
 	return NULL;
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 8b760ec..f38f582 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -51,6 +51,8 @@ RROutputCreate (const char  *name,
 {
     RROutputPtr	output;
 
+    if (!RRInit())
+	return NULL;
     output = xalloc (sizeof (RROutputRec) + nameLength + 1);
     if (!output)
 	return NULL;
diff-tree 6245e9dd4719c5dc15ff45d49cf626123794038b (from 24abce8032940e96bb2ccf9e463a7fff6f36283a)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Tue Nov 21 16:52:28 2006 -0800

    Allocate correct size for RRPropertyRec (oops).
    
    Neglected to change the allocation size from sizeof (PropertyRec) to
    sizeof (RRPropertyRec). Lots of fun crashes this way.
    (cherry picked from commit 0626eb8e5c9fa05de6bdc9aa0c654f5148bf7cff)

diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index 5d4c865..a47f306 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -68,9 +68,10 @@ RRCreateOutputProperty (Atom property)
 {
     RRPropertyPtr   prop;
     
-    prop = (RRPropertyPtr)xalloc(sizeof(PropertyRec));
+    prop = (RRPropertyPtr)xalloc(sizeof(RRPropertyRec));
     if (!prop)
 	return NULL;
+    prop->next = NULL;
     prop->propertyName = property;
     prop->is_pending = FALSE;
     prop->range = FALSE;
diff-tree 24abce8032940e96bb2ccf9e463a7fff6f36283a (from f62ac3ec39c6593df476985c630e499864c19c72)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Tue Nov 21 01:15:26 2006 -0800

    Change RandR property datatype to include pending/valid values.
    
    This patch tracks the protocol changes which introduce more complex
    semantics for RandR output properties including pending and valid value
    information.
    (cherry picked from commit af55c65bea40669fdc038aa34c6a1ec9ecb33e87)

diff --git a/randr/mirandr.c b/randr/mirandr.c
index 3a99bf9..0b763e1 100644
--- a/randr/mirandr.c
+++ b/randr/mirandr.c
@@ -64,10 +64,11 @@ miRRCrtcSetGamma (ScreenPtr	pScreen,
     return TRUE;
 }
 
-static Bool
-miRROutputSetProperty (ScreenPtr	pScreen,
-		       RROutputPtr	output,
-		       Atom	property)
+Bool
+miRROutputSetProperty (ScreenPtr	    pScreen,
+		       RROutputPtr	    output,
+		       Atom		    property,
+		       RRPropertyValuePtr   value)
 {
     return TRUE;
 }
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 19af9b9..27ede92 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -69,9 +69,11 @@ extern int (*SProcRandrVector[RRNumberRe
  */
 
 #define RRModeName(pMode) ((char *) (pMode + 1))
-typedef struct _rrMode	    RRModeRec, *RRModePtr;
-typedef struct _rrCrtc	    RRCrtcRec, *RRCrtcPtr;
-typedef struct _rrOutput    RROutputRec, *RROutputPtr;
+typedef struct _rrMode		RRModeRec, *RRModePtr;
+typedef struct _rrPropertyValue	RRPropertyValueRec, *RRPropertyValuePtr;
+typedef struct _rrProperty	RRPropertyRec, *RRPropertyPtr;
+typedef struct _rrCrtc		RRCrtcRec, *RRCrtcPtr;
+typedef struct _rrOutput	RROutputRec, *RROutputPtr;
 
 struct _rrMode {
     int		    refcnt;
@@ -81,6 +83,24 @@ struct _rrMode {
     Bool	    userDefined;
 };
 
+struct _rrPropertyValue {
+    Atom	    type;       /* ignored by server */
+    short	    format;     /* format of data for swapping - 8,16,32 */
+    long	    size;	/* size of data in (format/8) bytes */
+    pointer         data;	/* private to client */
+};
+
+struct _rrProperty {
+    RRPropertyPtr   next;
+    ATOM 	    propertyName;
+    Bool	    is_pending;
+    Bool	    range;
+    Bool	    immutable;
+    int		    num_valid;
+    INT32	    *valid_values;
+    RRPropertyValueRec	current, pending;
+};
+
 struct _rrCrtc {
     RRCrtc	    id;
     ScreenPtr	    pScreen;
@@ -116,7 +136,7 @@ struct _rrOutput {
     int		    numPreferred;
     RRModePtr	    *modes;
     Bool	    changed;
-    PropertyPtr	    properties;
+    RRPropertyPtr   properties;
     void	    *devPrivate;
 };
 
@@ -139,9 +159,10 @@ typedef Bool (*RRCrtcSetProcPtr) (Screen
 typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr	pScreen,
 				       RRCrtcPtr	crtc);
 
-typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr	pScreen,
-					    RROutputPtr	output,
-					    Atom	property);
+typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr		pScreen,
+					    RROutputPtr		output,
+					    Atom		property,
+					    RRPropertyValuePtr	value);
 
 #endif
 
@@ -363,6 +384,12 @@ miRRCrtcSet (ScreenPtr	pScreen,
 	     int	numOutput,
 	     RROutputPtr *outputs);
 
+Bool
+miRROutputSetProperty (ScreenPtr	    pScreen,
+		       RROutputPtr	    output,
+		       Atom		    property,
+		       RRPropertyValuePtr   value);
+
 /* randr.c */
 /*
  * Send all pending events
@@ -676,6 +703,12 @@ RRPointerScreenConfigured (ScreenPtr pSc
 void
 RRDeleteAllOutputProperties (RROutputPtr output);
 
+RRPropertyValuePtr
+RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending);
+
+RRPropertyPtr
+RRQueryOutputProperty (RROutputPtr output, Atom property);
+		       
 void
 RRDeleteOutputProperty (RROutputPtr output, Atom property);
 
@@ -685,6 +718,10 @@ RRChangeOutputProperty (RROutputPtr outp
 			pointer value, Bool sendevent);
 
 int
+RRConfigureOutputProperty (RROutputPtr output, Atom property,
+			   Bool pending, Bool range, Bool immutable,
+			   int num_values, INT32 *values);
+int
 ProcRRChangeOutputProperty (ClientPtr client);
 
 int
@@ -694,6 +731,12 @@ int
 ProcRRListOutputProperties (ClientPtr client);
 
 int
+ProcRRQueryOutputProperty (ClientPtr client);
+
+int
+ProcRRConfigureOutputProperty (ClientPtr client);
+
+int
 ProcRRDeleteOutputProperty (ClientPtr client);
 
 /* rrxinerama.c */
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index 49ba10b..6b61b9c 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -192,17 +192,19 @@ int (*ProcRandrVector[RRNumberRequests])
     ProcRRGetScreenResources,	/* 8 */
     ProcRRGetOutputInfo,	/* 9 */
     ProcRRListOutputProperties,	/* 10 */
-    ProcRRChangeOutputProperty,	/* 11 */
-    ProcRRDeleteOutputProperty,	/* 12 */
-    ProcRRGetOutputProperty,	/* 13 */
-    ProcRRCreateMode,		/* 14 */
-    ProcRRDestroyMode,		/* 15 */
-    ProcRRAddOutputMode,	/* 16 */
-    ProcRRDeleteOutputMode,	/* 17 */
-    ProcRRGetCrtcInfo,		/* 18 */
-    ProcRRSetCrtcConfig,	/* 19 */
-    ProcRRGetCrtcGammaSize,	/* 20 */
-    ProcRRGetCrtcGamma,		/* 21 */
-    ProcRRSetCrtcGamma,		/* 22 */
+    ProcRRQueryOutputProperty,	/* 11 */
+    ProcRRConfigureOutputProperty,  /* 12 */
+    ProcRRChangeOutputProperty,	/* 13 */
+    ProcRRDeleteOutputProperty,	/* 14 */
+    ProcRRGetOutputProperty,	/* 15 */
+    ProcRRCreateMode,		/* 16 */
+    ProcRRDestroyMode,		/* 17 */
+    ProcRRAddOutputMode,	/* 18 */
+    ProcRRDeleteOutputMode,	/* 19 */
+    ProcRRGetCrtcInfo,		/* 20 */
+    ProcRRSetCrtcConfig,	/* 21 */
+    ProcRRGetCrtcGammaSize,	/* 22 */
+    ProcRRGetCrtcGamma,		/* 23 */
+    ProcRRSetCrtcGamma,		/* 24 */
 };
 
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index 44f1f0a..5d4c865 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -33,7 +33,7 @@ RRDeliverEvent (ScreenPtr pScreen, xEven
 void
 RRDeleteAllOutputProperties (RROutputPtr output)
 {
-    PropertyPtr prop, next;
+    RRPropertyPtr prop, next;
     xRROutputPropertyNotifyEvent    event;
 
     for (prop = output->properties; prop; prop = next)
@@ -46,15 +46,58 @@ RRDeleteAllOutputProperties (RROutputPtr
 	event.atom = prop->propertyName;
 	event.timestamp = currentTime.milliseconds;
 	RRDeliverEvent (output->pScreen, (xEvent *) &event, RROutputPropertyNotifyMask);
-        xfree(prop->data);
+	if (prop->current.data)
+	    xfree(prop->current.data);
+	if (prop->pending.data)
+	    xfree(prop->pending.data);
         xfree(prop);
     }
 }
 
+static void
+RRInitOutputPropertyValue (RRPropertyValuePtr property_value)
+{
+    property_value->type = None;
+    property_value->format = 0;
+    property_value->size = 0;
+    property_value->data = NULL;
+}
+
+static RRPropertyPtr
+RRCreateOutputProperty (Atom property)
+{
+    RRPropertyPtr   prop;
+    
+    prop = (RRPropertyPtr)xalloc(sizeof(PropertyRec));
+    if (!prop)
+	return NULL;
+    prop->propertyName = property;
+    prop->is_pending = FALSE;
+    prop->range = FALSE;
+    prop->immutable = FALSE;
+    prop->num_valid = 0;
+    prop->valid_values = NULL;
+    RRInitOutputPropertyValue (&prop->current);
+    RRInitOutputPropertyValue (&prop->pending);
+    return prop;
+}
+
+static void
+RRDestroyOutputProperty (RRPropertyPtr prop)
+{
+    if (prop->valid_values)
+	xfree (prop->valid_values);
+    if (prop->current.data)
+	xfree(prop->current.data);
+    if (prop->pending.data)
+	xfree(prop->pending.data);
+    xfree(prop);
+}
+
 void
 RRDeleteOutputProperty (RROutputPtr output, Atom property)
 {
-    PropertyPtr	prop, *prev;
+    RRPropertyPtr	prop, *prev;
     xRROutputPropertyNotifyEvent    event;
 
     for (prev = &output->properties; (prop = *prev); prev = &(prop->next))
@@ -70,8 +113,7 @@ RRDeleteOutputProperty (RROutputPtr outp
 	event.atom = prop->propertyName;
 	event.timestamp = currentTime.milliseconds;
 	RRDeliverEvent (output->pScreen, (xEvent *) &event, RROutputPropertyNotifyMask);
-        xfree(prop->data);
-        xfree(prop);
+	RRDestroyOutputProperty (prop);
     }
 }
 
@@ -80,96 +122,95 @@ RRChangeOutputProperty (RROutputPtr outp
 			int format, int mode, unsigned long len,
 			pointer value, Bool sendevent)
 {
-    PropertyPtr			    prop;
+    RRPropertyPtr		    prop;
     xRROutputPropertyNotifyEvent    event;
     int				    sizeInBytes;
     int				    totalSize;
     pointer			    data;
+    RRPropertyValuePtr		    prop_value;
+    Bool			    add = FALSE;
 
     sizeInBytes = format >> 3;
     totalSize = len * sizeInBytes;
 
     /* first see if property already exists */
-
-    for (prop = output->properties; prop; prop = prop->next)
-	if (prop->propertyName == property)
-	    break;
-    
+    prop = RRQueryOutputProperty (output, property);
     if (!prop)   /* just add to list */
     {
-        prop = (PropertyPtr)xalloc(sizeof(PropertyRec));
+        prop = RRCreateOutputProperty (property);
 	if (!prop)
 	    return(BadAlloc);
-        data = (pointer)xalloc(totalSize);
-	if (!data && len)
-	{
-	    xfree(prop);
-	    return(BadAlloc);
-	}
-        prop->propertyName = property;
-        prop->type = type;
-        prop->format = format;
-        prop->data = data;
-	if (len)
-	    memmove((char *)data, (char *)value, totalSize);
-	prop->size = len;
-        prop->next = output->properties;
-        output->properties = prop;
+	add = TRUE;
+	mode = PropModeReplace;
     }
+    if (prop->is_pending)
+	prop_value = &prop->pending;
     else
+	prop_value = &prop->current;
+    
+    /* To append or prepend to a property the request format and type
+	    must match those of the already defined property.  The
+	    existing format and type are irrelevant when using the mode
+	    "PropModeReplace" since they will be written over. */
+
+    if ((format != prop_value->format) && (mode != PropModeReplace))
+	return(BadMatch);
+    if ((prop_value->type != type) && (mode != PropModeReplace))
+	return(BadMatch);
+    if (mode == PropModeReplace)
     {
-	/* To append or prepend to a property the request format and type
-		must match those of the already defined property.  The
-		existing format and type are irrelevant when using the mode
-		"PropModeReplace" since they will be written over. */
-
-        if ((format != prop->format) && (mode != PropModeReplace))
-	    return(BadMatch);
-        if ((prop->type != type) && (mode != PropModeReplace))
-            return(BadMatch);
-        if (mode == PropModeReplace)
-        {
-	    if (totalSize != prop->size * (prop->format >> 3))
-	    {
-	    	data = (pointer)xrealloc(prop->data, totalSize);
-	    	if (!data && len)
-		    return(BadAlloc);
-            	prop->data = data;
-	    }
-	    if (len)
-		memmove((char *)prop->data, (char *)value, totalSize);
-	    prop->size = len;
-    	    prop->type = type;
-	    prop->format = format;
-	}
-	else if (len == 0)
+	if (totalSize != prop_value->size * (prop_value->format >> 3))
 	{
-	    /* do nothing */
-	}
-        else if (mode == PropModeAppend)
-        {
-	    data = (pointer)xrealloc(prop->data,
-				     sizeInBytes * (len + prop->size));
-	    if (!data)
-		return(BadAlloc);
-            prop->data = data;
-	    memmove(&((char *)data)[prop->size * sizeInBytes], 
-		    (char *)value,
-		  totalSize);
-            prop->size += len;
-	}
-        else if (mode == PropModePrepend)
-        {
-            data = (pointer)xalloc(sizeInBytes * (len + prop->size));
-	    if (!data)
+	    if (prop_value->data)
+		data = (pointer)xrealloc(prop_value->data, totalSize);
+	    else
+		data = (pointer)xalloc (totalSize);
+	    if (!data && len)
+	    {
+		if (add)
+		    RRDestroyOutputProperty (prop);
 		return(BadAlloc);
-	    memmove(&((char *)data)[totalSize], (char *)prop->data, 
-		  (int)(prop->size * sizeInBytes));
-            memmove((char *)data, (char *)value, totalSize);
-	    xfree(prop->data);
-            prop->data = data;
-            prop->size += len;
+	    }
+	    prop_value->data = data;
 	}
+	if (len)
+	    memmove((char *)prop_value->data, (char *)value, totalSize);
+	prop_value->size = len;
+	prop_value->type = type;
+	prop_value->format = format;
+    }
+    else if (len == 0)
+    {
+	/* do nothing */
+    }
+    else if (mode == PropModeAppend)
+    {
+	data = (pointer)xrealloc(prop_value->data,
+				 sizeInBytes * (len + prop_value->size));
+	if (!data)
+	    return(BadAlloc);
+	prop_value->data = data;
+	memmove(&((char *)data)[prop_value->size * sizeInBytes], 
+		(char *)value,
+	      totalSize);
+	prop_value->size += len;
+    }
+    else if (mode == PropModePrepend)
+    {
+	data = (pointer)xalloc(sizeInBytes * (len + prop_value->size));
+	if (!data)
+	    return(BadAlloc);
+	memmove(&((char *)data)[totalSize], (char *)prop_value->data, 
+	      (int)(prop_value->size * sizeInBytes));
+	memmove((char *)data, (char *)value, totalSize);
+	xfree(prop_value->data);
+	prop_value->data = data;
+	prop_value->size += len;
+    }
+    if (add)
+    {
+	prop->next = output->properties;
+	output->properties = prop;
     }
     if (sendevent)
     {
@@ -184,6 +225,81 @@ RRChangeOutputProperty (RROutputPtr outp
     return(Success);
 }
 
+RRPropertyPtr
+RRQueryOutputProperty (RROutputPtr output, Atom property)
+{
+    RRPropertyPtr   prop;
+    
+    for (prop = output->properties; prop; prop = prop->next)
+	if (prop->propertyName == property)
+	    return prop;
+    return NULL;
+}
+		       
+RRPropertyValuePtr
+RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending)
+{
+    RRPropertyPtr   prop = RRQueryOutputProperty (output, property);
+
+    if (!prop)
+	return NULL;
+    if (pending && prop->is_pending)
+	return &prop->pending;
+    else
+	return &prop->current;
+}
+
+int
+RRConfigureOutputProperty (RROutputPtr output, Atom property,
+			   Bool pending, Bool range, Bool immutable,
+			   int num_values, INT32 *values)
+{
+    RRPropertyPtr   prop = RRQueryOutputProperty (output, property);
+    Bool	    add = FALSE;
+    INT32	    *new_values;
+
+    if (!prop)
+    {
+        prop = RRCreateOutputProperty (property);
+	if (!prop)
+	    return(BadAlloc);
+	add = TRUE;
+    } else if (prop->immutable && !immutable)
+	return(BadAccess);
+    
+    /*
+     * ranges must have even number of values
+     */
+    if (range && (num_values & 1))
+	return BadMatch;
+
+    new_values = xalloc (num_values * sizeof (INT32));
+    if (!new_values && num_values)
+	return BadAlloc;
+    if (num_values)
+	memcpy (new_values, values, num_values * sizeof (INT32));
+    
+    /*
+     * Property moving from pending to non-pending
+     * loses any pending values
+     */
+    if (prop->is_pending && !pending)
+    {
+	if (prop->pending.data)
+	    xfree (prop->pending.data);
+	RRInitOutputPropertyValue (&prop->pending);
+    }
+
+    prop->is_pending = pending;
+    prop->range = range;
+    prop->immutable = immutable;
+    prop->num_valid = num_values;
+    if (prop->valid_values)
+	xfree (prop->valid_values);
+    prop->valid_values = new_values;
+    return Success;
+}
+
 int
 ProcRRListOutputProperties (ClientPtr client)
 {
@@ -192,7 +308,7 @@ ProcRRListOutputProperties (ClientPtr cl
     xRRListOutputPropertiesReply    rep;
     int				    numProps = 0;
     RROutputPtr			    output;
-    PropertyPtr			    prop;
+    RRPropertyPtr			    prop;
     
     REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq);
 
@@ -211,6 +327,12 @@ ProcRRListOutputProperties (ClientPtr cl
     rep.nProperties = numProps;
     rep.length = (numProps * sizeof(Atom)) >> 2;
     rep.sequenceNumber = client->sequence;
+    if (client->swapped) 
+    {
+	int n;
+	swaps (&rep.sequenceNumber, n);
+	swapl (&rep.length, n);
+    }
     temppAtoms = pAtoms;
     for (prop = output->properties; prop; prop = prop->next)
 	*temppAtoms++ = prop->propertyName;
@@ -226,6 +348,68 @@ ProcRRListOutputProperties (ClientPtr cl
 }
 
 int
+ProcRRQueryOutputProperty (ClientPtr client)
+{
+    REQUEST(xRRQueryOutputPropertyReq);
+    xRRQueryOutputPropertyReply	    rep;
+    RROutputPtr			    output;
+    RRPropertyPtr		    prop;
+    
+    REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
+
+    output = LookupOutput (client, stuff->output, SecurityReadAccess);
+    
+    if (!output)
+        return RRErrorBase + BadRROutput;
+    
+    prop = RRQueryOutputProperty (output, stuff->property);
+    if (!prop)
+	return BadName;
+    
+    rep.type = X_Reply;
+    rep.length = prop->num_valid;
+    rep.sequenceNumber = client->sequence;
+    rep.pending = prop->is_pending;
+    rep.range = prop->range;
+    rep.immutable = prop->immutable;
+    if (client->swapped) 
+    {
+	int n;
+	swaps (&rep.sequenceNumber, n);
+	swapl (&rep.length, n);
+    }
+    WriteReplyToClient (client, sizeof (xRRQueryOutputPropertyReply), &rep);
+    if (prop->num_valid)
+    {
+        client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+        WriteSwappedDataToClient(client, prop->num_valid * sizeof(INT32),
+				 prop->valid_values);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcRRConfigureOutputProperty (ClientPtr client)
+{
+    REQUEST(xRRConfigureOutputPropertyReq);
+    RROutputPtr				output;
+    int					num_valid;
+    
+    REQUEST_SIZE_MATCH(xRRConfigureOutputPropertyReq);
+
+    output = LookupOutput (client, stuff->output, SecurityReadAccess);
+    
+    if (!output)
+        return RRErrorBase + BadRROutput;
+    
+    num_valid = stuff->length - (sizeof (xRRConfigureOutputPropertyReq) >> 2);
+    return RRConfigureOutputProperty (output, stuff->property,
+				      stuff->pending, stuff->range,
+				      FALSE, num_valid, 
+				      (INT32 *) (stuff + 1));
+}
+
+int
 ProcRRChangeOutputProperty (ClientPtr client)
 {
     REQUEST(xRRChangeOutputPropertyReq);
@@ -309,7 +493,8 @@ int
 ProcRRGetOutputProperty (ClientPtr client)
 {
     REQUEST(xRRGetOutputPropertyReq);
-    PropertyPtr			prop, *prev;
+    RRPropertyPtr			prop, *prev;
+    RRPropertyValuePtr			prop_value;
     unsigned long		n, len, ind;
     RROutputPtr			output;
     xRRGetOutputPropertyReply	reply;
@@ -356,18 +541,26 @@ ProcRRGetOutputProperty (ClientPtr clien
 	return(client->noClientException);
     }
 
+    if (prop->immutable && stuff->delete)
+	return BadAccess;
+
+    if (stuff->pending && prop->is_pending)
+	prop_value = &prop->pending;
+    else
+	prop_value = &prop->current;
+    
     /* If the request type and actual type don't match. Return the
     property information, but not the data. */
 
-    if (((stuff->type != prop->type) &&
+    if (((stuff->type != prop_value->type) &&
 	 (stuff->type != AnyPropertyType))
        )
     {
-	reply.bytesAfter = prop->size;
-	reply.format = prop->format;
+	reply.bytesAfter = prop_value->size;
+	reply.format = prop_value->format;
 	reply.length = 0;
 	reply.nItems = 0;
-	reply.propertyType = prop->type;
+	reply.propertyType = prop_value->type;
 	WriteReplyToClient(client, sizeof(xRRGetOutputPropertyReply), &reply);
 	return(client->noClientException);
     }
@@ -375,7 +568,7 @@ ProcRRGetOutputProperty (ClientPtr clien
 /*
  *  Return type, format, value to client
  */
-    n = (prop->format/8) * prop->size; /* size (bytes) of prop */
+    n = (prop_value->format/8) * prop_value->size; /* size (bytes) of prop */
     ind = stuff->longOffset << 2;        
 
    /* If longOffset is invalid such that it causes "len" to
@@ -390,10 +583,10 @@ ProcRRGetOutputProperty (ClientPtr clien
     len = min(n - ind, 4 * stuff->longLength);
 
     reply.bytesAfter = n - (ind + len);
-    reply.format = prop->format;
+    reply.format = prop_value->format;
     reply.length = (len + 3) >> 2;
-    reply.nItems = len / (prop->format / 8 );
-    reply.propertyType = prop->type;
+    reply.nItems = len / (prop_value->format / 8 );
+    reply.propertyType = prop_value->type;
 
     if (stuff->delete && (reply.bytesAfter == 0))
     {
@@ -417,14 +610,13 @@ ProcRRGetOutputProperty (ClientPtr clien
 	default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
 	}
 	WriteSwappedDataToClient(client, len,
-				 (char *)prop->data + ind);
+				 (char *)prop_value->data + ind);
     }
 
     if (stuff->delete && (reply.bytesAfter == 0))
     { /* delete the Property */
 	*prev = prop->next;
-	xfree(prop->data);
-	xfree(prop);
+	RRDestroyOutputProperty (prop);
     }
     return(client->noClientException);
 }
diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c
index 67af753..4a6a6e4 100644
--- a/randr/rrsdispatch.c
+++ b/randr/rrsdispatch.c
@@ -132,6 +132,26 @@ SProcRRListOutputProperties (ClientPtr c
 }
 
 static int
+SProcRRQueryOutputProperty (ClientPtr client)
+{
+    REQUEST(xRRQueryOutputPropertyReq);
+    
+    REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
+    (void) stuff;
+    return BadImplementation; 
+}
+
+static int
+SProcRRConfigureOutputProperty (ClientPtr client)
+{
+    REQUEST(xRRConfigureOutputPropertyReq);
+    
+    REQUEST_SIZE_MATCH(xRRConfigureOutputPropertyReq);
+    (void) stuff;
+    return BadImplementation; 
+}
+
+static int
 SProcRRChangeOutputProperty (ClientPtr client)
 {
     REQUEST(xRRChangeOutputPropertyReq);
@@ -267,17 +287,19 @@ int (*SProcRandrVector[RRNumberRequests]
     SProcRRGetScreenResources,	/* 8 */
     SProcRRGetOutputInfo,	/* 9 */
     SProcRRListOutputProperties,/* 10 */
-    SProcRRChangeOutputProperty,/* 11 */
-    SProcRRDeleteOutputProperty,/* 12 */
-    SProcRRGetOutputProperty,	/* 13 */
-    SProcRRCreateMode,		/* 14 */
-    SProcRRDestroyMode,		/* 15 */
-    SProcRRAddOutputMode,	/* 16 */
-    SProcRRDeleteOutputMode,	/* 17 */
-    SProcRRGetCrtcInfo,		/* 18 */
-    SProcRRSetCrtcConfig,	/* 19 */
-    SProcRRGetCrtcGammaSize,	/* 20 */
-    SProcRRGetCrtcGamma,	/* 21 */
-    SProcRRSetCrtcGamma,	/* 22 */
+    SProcRRQueryOutputProperty,	/* 11 */
+    SProcRRConfigureOutputProperty,  /* 12 */
+    SProcRRChangeOutputProperty,/* 13 */
+    SProcRRDeleteOutputProperty,/* 14 */
+    SProcRRGetOutputProperty,	/* 15 */
+    SProcRRCreateMode,		/* 16 */
+    SProcRRDestroyMode,		/* 17 */
+    SProcRRAddOutputMode,	/* 18 */
+    SProcRRDeleteOutputMode,	/* 19 */
+    SProcRRGetCrtcInfo,		/* 20 */
+    SProcRRSetCrtcConfig,	/* 21 */
+    SProcRRGetCrtcGammaSize,	/* 22 */
+    SProcRRGetCrtcGamma,	/* 23 */
+    SProcRRSetCrtcGamma,	/* 24 */
 };
 
diff-tree f62ac3ec39c6593df476985c630e499864c19c72 (from fbd09443385c533416fa530399d54f130afaf985)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Nov 28 10:31:40 2006 -0800

    Separate DDC mode list creation from MonPtr creation.
    
    This will be used by the intel driver, and likely other RandR 1.2 drivers.

diff --git a/hw/xfree86/ddc/edid_modes.c b/hw/xfree86/ddc/edid_modes.c
index 25f95ca..cfc8ddc 100644
--- a/hw/xfree86/ddc/edid_modes.c
+++ b/hw/xfree86/ddc/edid_modes.c
@@ -204,6 +204,46 @@ DDCGuessRangesFromModes(int scrnIndex, M
     }
 }
 
+DisplayModePtr
+xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
+{
+    int preferred, i;
+    DisplayModePtr Modes = NULL, Mode;
+
+    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
+
+    /* Add established timings */
+    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    /* Add standard timings */
+    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    for (i = 0; i < DET_TIMINGS; i++) {
+	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
+
+        switch (det_mon->type) {
+        case DT:
+            Mode = DDCModeFromDetailedTiming(scrnIndex,
+                                             &det_mon->section.d_timings,
+					     preferred);
+	    preferred = 0;
+            Modes = xf86ModesAdd(Modes, Mode);
+            break;
+        case DS_STD_TIMINGS:
+            Mode = DDCModesFromStandardTiming(scrnIndex,
+					      det_mon->section.std_t);
+            Modes = xf86ModesAdd(Modes, Mode);
+            break;
+        default:
+            break;
+        }
+    }
+
+    return Modes;
+}
+
 /*
  * Fill out MonPtr with xf86MonPtr information.
  */
@@ -213,15 +253,12 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr 
     DisplayModePtr Modes = NULL, Mode;
     int i, clock;
     Bool have_hsync = FALSE, have_vrefresh = FALSE;
-    int preferred;
 
     if (!Monitor || !DDC)
         return;
 
     Monitor->DDC = DDC;
 
-    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
-
     Monitor->widthmm = 10 * DDC->features.hsize;
     Monitor->heightmm = 10 * DDC->features.vsize;
 
@@ -230,20 +267,14 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr 
         Monitor->reducedblanking = TRUE;
     /* Allow the user to also enable this through config */
 
-    /* Add established timings */
-    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1);
-    Modes = xf86ModesAdd(Modes, Mode);
-
-    /* Add standard timings */
-    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2);
-    Modes = xf86ModesAdd(Modes, Mode);
+    Modes = xf86DDCGetModes(scrnIndex, DDC);
 
     /* Skip EDID ranges if they were specified in the config file */
     have_hsync = (Monitor->nHsync != 0);
     have_vrefresh = (Monitor->nVrefresh != 0);
 
     /* Go through the detailed monitor sections */
-    for (i = 0; i < DET_TIMINGS; i++)
+    for (i = 0; i < DET_TIMINGS; i++) {
         switch (DDC->det_mon[i].type) {
         case DS_RANGES:
 	    if (!have_hsync) {
@@ -279,21 +310,10 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr 
 		Monitor->maxPixClock = clock;
 
             break;
-        case DT:
-            Mode = DDCModeFromDetailedTiming(scrnIndex,
-                                             &DDC->det_mon[i].section.d_timings,
-					     preferred);
-	    preferred = 0;
-            Modes = xf86ModesAdd(Modes, Mode);
-            break;
-        case DS_STD_TIMINGS:
-            Mode = DDCModesFromStandardTiming(scrnIndex,
-                                             DDC->det_mon[i].section.std_t);
-            Modes = xf86ModesAdd(Modes, Mode);
-            break;
         default:
             break;
         }
+    }
 
     if (Modes) {
         /* Print Modes */
diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h
index 5def97a..7799471 100644
--- a/hw/xfree86/ddc/xf86DDC.h
+++ b/hw/xfree86/ddc/xf86DDC.h
@@ -59,6 +59,8 @@ extern void xf86print_vdif(
     xf86vdifPtr v
 );
 
+DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
+
 #endif
 
 
diff-tree fbd09443385c533416fa530399d54f130afaf985 (from 4ad0bde661be2af4a17771d66066d49736e85cbe)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Nov 28 10:15:51 2006 -0800

    Replace bad mode name-setting code with xf86SetModeDefaultName().

diff --git a/hw/xfree86/ddc/edid_modes.c b/hw/xfree86/ddc/edid_modes.c
index 9e824b1..25f95ca 100644
--- a/hw/xfree86/ddc/edid_modes.c
+++ b/hw/xfree86/ddc/edid_modes.c
@@ -124,10 +124,6 @@ DDCModeFromDetailedTiming(int scrnIndex,
     Mode = xnfalloc(sizeof(DisplayModeRec));
     memset(Mode, 0, sizeof(DisplayModeRec));
 
-    Mode->name = xnfalloc(10); /* "1234x1234" */
-    xf86snprintf(Mode->name, 20, "%dx%d", timing->h_active,
-                 timing->v_active);
-
     Mode->type = M_T_DRIVER;
     if (preferred)
 	Mode->type |= M_T_PREFERRED;
@@ -144,6 +140,8 @@ DDCModeFromDetailedTiming(int scrnIndex,
     Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
     Mode->VTotal = timing->v_active + timing->v_blanking;
 
+    xf86SetModeDefaultName(Mode);
+
     /* We ignore h/v_size and h/v_border for now. */
 
     if (timing->interlaced)
diff-tree 4ad0bde661be2af4a17771d66066d49736e85cbe (from 05778432dc6e688bc0beff0c20ffd7e27b74888e)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Nov 28 10:12:02 2006 -0800

    Clean up a bunch of long lines and trailing whitespace.

diff --git a/hw/xfree86/ddc/edid_modes.c b/hw/xfree86/ddc/edid_modes.c
index 5ce86ee..9e824b1 100644
--- a/hw/xfree86/ddc/edid_modes.c
+++ b/hw/xfree86/ddc/edid_modes.c
@@ -85,14 +85,15 @@ DDCModesFromStandardTiming(int scrnIndex
 {
     DisplayModePtr Modes = NULL, Mode = NULL;
     int i;
-    
-    for (i = 0; i < STD_TIMINGS; i++)
+
+    for (i = 0; i < STD_TIMINGS; i++) {
         if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
             Mode =  xf86CVTMode(timing[i].hsize, timing[i].vsize,
                                 timing[i].refresh, FALSE, FALSE);
 	    Mode->type = M_T_DRIVER;
             Modes = xf86ModesAdd(Modes, Mode);
         }
+    }
 
     return Modes;
 }
@@ -108,55 +109,56 @@ DDCModeFromDetailedTiming(int scrnIndex,
 
     /* We don't do stereo */
     if (timing->stereo) {
-        xf86DrvMsg(scrnIndex, X_INFO, "%s: Ignoring: We don't handle stereo.\n",
-                   __func__);
+        xf86DrvMsg(scrnIndex, X_INFO,
+		   "%s: Ignoring: We don't handle stereo.\n", __func__);
         return NULL;
     }
-    
+
     /* We only do seperate sync currently */
     if (timing->sync != 0x03) {
-         xf86DrvMsg(scrnIndex, X_INFO, "%s: %dx%d Warning: We only handle seperate"
+         xf86DrvMsg(scrnIndex, X_INFO,
+		    "%s: %dx%d Warning: We only handle seperate"
                     " sync.\n", __func__, timing->h_active, timing->v_active);
     }
-    
+
     Mode = xnfalloc(sizeof(DisplayModeRec));
     memset(Mode, 0, sizeof(DisplayModeRec));
-    
+
     Mode->name = xnfalloc(10); /* "1234x1234" */
     xf86snprintf(Mode->name, 20, "%dx%d", timing->h_active,
                  timing->v_active);
-    
+
     Mode->type = M_T_DRIVER;
     if (preferred)
 	Mode->type |= M_T_PREFERRED;
-    
+
     Mode->Clock = timing->clock / 1000.0;
-    
+
     Mode->HDisplay = timing->h_active;
     Mode->HSyncStart = timing->h_active + timing->h_sync_off;
     Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
     Mode->HTotal = timing->h_active + timing->h_blanking;
-    
+
     Mode->VDisplay = timing->v_active;
     Mode->VSyncStart = timing->v_active + timing->v_sync_off;
     Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
     Mode->VTotal = timing->v_active + timing->v_blanking;
-    
+
     /* We ignore h/v_size and h/v_border for now. */
-    
+
     if (timing->interlaced)
         Mode->Flags |= V_INTERLACE;
-    
+
     if (timing->misc & 0x02)
         Mode->Flags |= V_PHSYNC;
     else
         Mode->Flags |= V_NHSYNC;
-    
+
     if (timing->misc & 0x01)
         Mode->Flags |= V_PVSYNC;
     else
         Mode->Flags |= V_NVSYNC;
- 
+
     return Mode;
 }
 
@@ -199,7 +201,7 @@ DDCGuessRangesFromModes(int scrnIndex, M
 
         if (Mode->VRefresh > Monitor->vrefresh[0].hi)
             Monitor->vrefresh[0].hi = Mode->VRefresh;
-        
+
         Mode = Mode->next;
     }
 }
@@ -214,7 +216,7 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr 
     int i, clock;
     Bool have_hsync = FALSE, have_vrefresh = FALSE;
     int preferred;
-    
+
     if (!Monitor || !DDC)
         return;
 
@@ -224,9 +226,9 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr 
 
     Monitor->widthmm = 10 * DDC->features.hsize;
     Monitor->heightmm = 10 * DDC->features.vsize;
-    
+
     /* If this is a digital display, then we can use reduced blanking */
-    if (DDC->features.input_type) 
+    if (DDC->features.input_type)
         Monitor->reducedblanking = TRUE;
     /* Allow the user to also enable this through config */
 
@@ -280,7 +282,7 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr 
 
             break;
         case DT:
-            Mode = DDCModeFromDetailedTiming(scrnIndex, 
+            Mode = DDCModeFromDetailedTiming(scrnIndex,
                                              &DDC->det_mon[i].section.d_timings,
 					     preferred);
 	    preferred = 0;
@@ -314,7 +316,7 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr 
 
         while (Mode->next)
             Mode = Mode->next;
-        
+
         /* add to MonPtr */
         if (Monitor->Modes) {
             Monitor->Last->next = Modes;
diff-tree 05778432dc6e688bc0beff0c20ffd7e27b74888e (from 38ecc66cd9c61346a46697bbf1d8319f4f6f9800)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Nov 28 10:07:57 2006 -0800

    Move code to get a mode list from EDID data from ddcProperty.c to edid_modes.c.

diff --git a/hw/xfree86/ddc/Makefile.am b/hw/xfree86/ddc/Makefile.am
index aff8cd3..a04b5e8 100644
--- a/hw/xfree86/ddc/Makefile.am
+++ b/hw/xfree86/ddc/Makefile.am
@@ -4,7 +4,8 @@ module_LTLIBRARIES = libddc.la
 
 libddc_la_LDFLAGS = -avoid-version
 libddc_la_SOURCES = xf86DDC.c edid.c interpret_edid.c print_edid.c \
-                   interpret_vdif.c print_vdif.c ddcProperty.c
+                   interpret_vdif.c print_vdif.c ddcProperty.c \
+		    edid_modes.c
 
 INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c
 
diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c
index ddf580c..11b5e26 100644
--- a/hw/xfree86/ddc/ddcProperty.c
+++ b/hw/xfree86/ddc/ddcProperty.c
@@ -32,300 +32,8 @@
 #include "propertyst.h"
 #include "xf86DDC.h"
 
-/*
- * TODO:
- *  - for those with access to the VESA DMT standard; review please.
- */
-#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER
-#define MODESUFFIX   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
-
-DisplayModeRec DDCEstablishedModes[17] = {
-    { MODEPREFIX("800x600"),    40000,  800,  840,  968, 1056, 0,  600,  601,  605,  628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 60Hz */
-    { MODEPREFIX("800x600"),    36000,  800,  824,  896, 1024, 0,  600,  601,  603,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 56Hz */
-    { MODEPREFIX("640x480"),    31500,  640,  656,  720,  840, 0,  480,  481,  484,  500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 75Hz */
-    { MODEPREFIX("640x480"),    31500,  640,  664,  704,  832, 0,  480,  489,  491,  520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 72Hz */
-    { MODEPREFIX("640x480"),    30240,  640,  704,  768,  864, 0,  480,  483,  486,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 67Hz */
-    { MODEPREFIX("640x480"),    25200,  640,  656,  752,  800, 0,  480,  490,  492,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 60Hz */
-    { MODEPREFIX("720x400"),    35500,  720,  738,  846,  900, 0,  400,  421,  423,  449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400 at 88Hz */
-    { MODEPREFIX("720x400"),    28320,  720,  738,  846,  900, 0,  400,  412,  414,  449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400 at 70Hz */
-    { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024 at 75Hz */
-    { MODEPREFIX("1024x768"),   78800, 1024, 1040, 1136, 1312, 0,  768,  769,  772,  800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768 at 75Hz */
-    { MODEPREFIX("1024x768"),   75000, 1024, 1048, 1184, 1328, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 70Hz */
-    { MODEPREFIX("1024x768"),   65000, 1024, 1048, 1184, 1344, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 60Hz */
-    { MODEPREFIX("1024x768"),   44900, 1024, 1032, 1208, 1264, 0,  768,  768,  776,  817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768 at 43Hz */
-    { MODEPREFIX("832x624"),    57284,  832,  864,  928, 1152, 0,  624,  625,  628,  667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624 at 75Hz */
-    { MODEPREFIX("800x600"),    49500,  800,  816,  896, 1056, 0,  600,  601,  604,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 75Hz */
-    { MODEPREFIX("800x600"),    50000,  800,  856,  976, 1040, 0,  600,  637,  643,  666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 72Hz */
-    { MODEPREFIX("1152x864"),  108000, 1152, 1216, 1344, 1600, 0,  864,  865,  868,  900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864 at 75Hz */
-};
 
-static DisplayModePtr
-DDCModesFromEstablished(int scrnIndex, struct established_timings *timing)
-{
-    DisplayModePtr Modes = NULL, Mode = NULL;
-    CARD32 bits = (timing->t1) | (timing->t2 << 8) |
-        ((timing->t_manu & 0x80) << 9);
-    int i;
-
-    for (i = 0; i < 17; i++) {
-        if (bits & (0x01 << i)) {
-            Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
-            Modes = xf86ModesAdd(Modes, Mode);
-        }
-    }
-
-    return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing)
-{
-    DisplayModePtr Modes = NULL, Mode = NULL;
-    int i;
-    
-    for (i = 0; i < STD_TIMINGS; i++)
-        if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
-            Mode =  xf86CVTMode(timing[i].hsize, timing[i].vsize,
-                                timing[i].refresh, FALSE, FALSE);
-	    Mode->type = M_T_DRIVER;
-            Modes = xf86ModesAdd(Modes, Mode);
-        }
-
-    return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
-			  int preferred)
-{
-    DisplayModePtr Mode;
-
-    /* We don't do stereo */
-    if (timing->stereo) {
-        xf86DrvMsg(scrnIndex, X_INFO, "%s: Ignoring: We don't handle stereo.\n",
-                   __func__);
-        return NULL;
-    }
-    
-    /* We only do seperate sync currently */
-    if (timing->sync != 0x03) {
-         xf86DrvMsg(scrnIndex, X_INFO, "%s: %dx%d Warning: We only handle seperate"
-                    " sync.\n", __func__, timing->h_active, timing->v_active);
-    }
-    
-    Mode = xnfalloc(sizeof(DisplayModeRec));
-    memset(Mode, 0, sizeof(DisplayModeRec));
-    
-    Mode->name = xnfalloc(10); /* "1234x1234" */
-    xf86snprintf(Mode->name, 20, "%dx%d", timing->h_active,
-                 timing->v_active);
-    
-    Mode->type = M_T_DRIVER;
-    if (preferred)
-	Mode->type |= M_T_PREFERRED;
-    
-    Mode->Clock = timing->clock / 1000.0;
-    
-    Mode->HDisplay = timing->h_active;
-    Mode->HSyncStart = timing->h_active + timing->h_sync_off;
-    Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
-    Mode->HTotal = timing->h_active + timing->h_blanking;
-    
-    Mode->VDisplay = timing->v_active;
-    Mode->VSyncStart = timing->v_active + timing->v_sync_off;
-    Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
-    Mode->VTotal = timing->v_active + timing->v_blanking;
-    
-    /* We ignore h/v_size and h/v_border for now. */
-    
-    if (timing->interlaced)
-        Mode->Flags |= V_INTERLACE;
-    
-    if (timing->misc & 0x02)
-        Mode->Flags |= V_PHSYNC;
-    else
-        Mode->Flags |= V_NHSYNC;
-    
-    if (timing->misc & 0x01)
-        Mode->Flags |= V_PVSYNC;
-    else
-        Mode->Flags |= V_NVSYNC;
- 
-    return Mode;
-}
-
-/*
- *
- */
-static void
-DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
-{
-    DisplayModePtr Mode = Modes;
-
-    if (!Monitor || !Modes)
-        return;
-
-    /* set up the ranges for scanning through the modes */
-    Monitor->nHsync = 1;
-    Monitor->hsync[0].lo = 1024.0;
-    Monitor->hsync[0].hi = 0.0;
 
-    Monitor->nVrefresh = 1;
-    Monitor->vrefresh[0].lo = 1024.0;
-    Monitor->vrefresh[0].hi = 0.0;
-
-    while (Mode) {
-        if (!Mode->HSync)
-            Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
-
-        if (!Mode->VRefresh)
-            Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 
-                ((float) (Mode->HTotal * Mode->VTotal));
-
-        if (Mode->HSync < Monitor->hsync[0].lo)
-            Monitor->hsync[0].lo = Mode->HSync;
-
-        if (Mode->HSync > Monitor->hsync[0].hi)
-            Monitor->hsync[0].hi = Mode->HSync;
-
-        if (Mode->VRefresh < Monitor->vrefresh[0].lo)
-            Monitor->vrefresh[0].lo = Mode->VRefresh;
-
-        if (Mode->VRefresh > Monitor->vrefresh[0].hi)
-            Monitor->vrefresh[0].hi = Mode->VRefresh;
-        
-        Mode = Mode->next;
-    }
-}
-
-/*
- * Fill out MonPtr with xf86MonPtr information.
- */
-void
-xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
-{
-    DisplayModePtr Modes = NULL, Mode;
-    int i, clock;
-    Bool have_hsync = FALSE, have_vrefresh = FALSE;
-    int preferred;
-    
-    if (!Monitor || !DDC)
-        return;
-
-    Monitor->DDC = DDC;
-
-    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
-
-    Monitor->widthmm = 10 * DDC->features.hsize;
-    Monitor->heightmm = 10 * DDC->features.vsize;
-    
-    /* If this is a digital display, then we can use reduced blanking */
-    if (DDC->features.input_type) 
-        Monitor->reducedblanking = TRUE;
-    /* Allow the user to also enable this through config */
-
-    /* Add established timings */
-    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1);
-    Modes = xf86ModesAdd(Modes, Mode);
-
-    /* Add standard timings */
-    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2);
-    Modes = xf86ModesAdd(Modes, Mode);
-
-    /* Skip EDID ranges if they were specified in the config file */
-    have_hsync = (Monitor->nHsync != 0);
-    have_vrefresh = (Monitor->nVrefresh != 0);
-
-    /* Go through the detailed monitor sections */
-    for (i = 0; i < DET_TIMINGS; i++)
-        switch (DDC->det_mon[i].type) {
-        case DS_RANGES:
-	    if (!have_hsync) {
-		if (!Monitor->nHsync)
-		    xf86DrvMsg(scrnIndex, X_INFO,
-			    "Using EDID range info for horizontal sync\n");
-		Monitor->hsync[Monitor->nHsync].lo =
-		    DDC->det_mon[i].section.ranges.min_h;
-		Monitor->hsync[Monitor->nHsync].hi =
-		    DDC->det_mon[i].section.ranges.max_h;
-		Monitor->nHsync++;
-	    } else {
-		xf86DrvMsg(scrnIndex, X_INFO,
-			"Using hsync ranges from config file\n");
-	    }
-
-	    if (!have_vrefresh) {
-		if (!Monitor->nVrefresh)
-		    xf86DrvMsg(scrnIndex, X_INFO,
-			    "Using EDID range info for vertical refresh\n");
-		Monitor->vrefresh[Monitor->nVrefresh].lo =
-		    DDC->det_mon[i].section.ranges.min_v;
-		Monitor->vrefresh[Monitor->nVrefresh].hi =
-		    DDC->det_mon[i].section.ranges.max_v;
-		Monitor->nVrefresh++;
-	    } else {
-		xf86DrvMsg(scrnIndex, X_INFO,
-			"Using vrefresh ranges from config file\n");
-	    }
-
-	    clock = DDC->det_mon[i].section.ranges.max_clock * 1000;
-	    if (clock > Monitor->maxPixClock)
-		Monitor->maxPixClock = clock;
-
-            break;
-        case DT:
-            Mode = DDCModeFromDetailedTiming(scrnIndex, 
-                                             &DDC->det_mon[i].section.d_timings,
-					     preferred);
-	    preferred = 0;
-            Modes = xf86ModesAdd(Modes, Mode);
-            break;
-        case DS_STD_TIMINGS:
-            Mode = DDCModesFromStandardTiming(scrnIndex,
-                                             DDC->det_mon[i].section.std_t);
-            Modes = xf86ModesAdd(Modes, Mode);
-            break;
-        default:
-            break;
-        }
-
-    if (Modes) {
-        /* Print Modes */
-        xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n");
-
-        Mode = Modes;
-        while (Mode) {
-            xf86PrintModeline(scrnIndex, Mode);
-            Mode = Mode->next;
-        }
-
-        /* Do we still need ranges to be filled in? */
-        if (!Monitor->nHsync || !Monitor->nVrefresh)
-            DDCGuessRangesFromModes(scrnIndex, Monitor, Modes);
-
-        /* look for last Mode */
-        Mode = Modes;
-
-        while (Mode->next)
-            Mode = Mode->next;
-        
-        /* add to MonPtr */
-        if (Monitor->Modes) {
-            Monitor->Last->next = Modes;
-            Modes->prev = Monitor->Last;
-            Monitor->Last = Mode;
-        } else {
-            Monitor->Modes = Modes;
-            Monitor->Last = Mode;
-        }
-    }
-}
 
 #define EDID1_ATOM_NAME         "XFree86_DDC_EDID1_RAWDATA"
 #define EDID2_ATOM_NAME         "XFree86_DDC_EDID2_RAWDATA"
diff --git a/hw/xfree86/ddc/edid_modes.c b/hw/xfree86/ddc/edid_modes.c
new file mode 100644
index 0000000..5ce86ee
--- /dev/null
+++ b/hw/xfree86/ddc/edid_modes.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2006 Luc Verhaegen.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include <X11/Xatom.h>
+#include "property.h"
+#include "propertyst.h"
+#include "xf86DDC.h"
+
+/*
+ * TODO:
+ *  - for those with access to the VESA DMT standard; review please.
+ */
+#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER
+#define MODESUFFIX   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
+
+DisplayModeRec DDCEstablishedModes[17] = {
+    { MODEPREFIX("800x600"),    40000,  800,  840,  968, 1056, 0,  600,  601,  605,  628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 60Hz */
+    { MODEPREFIX("800x600"),    36000,  800,  824,  896, 1024, 0,  600,  601,  603,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 56Hz */
+    { MODEPREFIX("640x480"),    31500,  640,  656,  720,  840, 0,  480,  481,  484,  500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 75Hz */
+    { MODEPREFIX("640x480"),    31500,  640,  664,  704,  832, 0,  480,  489,  491,  520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 72Hz */
+    { MODEPREFIX("640x480"),    30240,  640,  704,  768,  864, 0,  480,  483,  486,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 67Hz */
+    { MODEPREFIX("640x480"),    25200,  640,  656,  752,  800, 0,  480,  490,  492,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 60Hz */
+    { MODEPREFIX("720x400"),    35500,  720,  738,  846,  900, 0,  400,  421,  423,  449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400 at 88Hz */
+    { MODEPREFIX("720x400"),    28320,  720,  738,  846,  900, 0,  400,  412,  414,  449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400 at 70Hz */
+    { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024 at 75Hz */
+    { MODEPREFIX("1024x768"),   78800, 1024, 1040, 1136, 1312, 0,  768,  769,  772,  800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768 at 75Hz */
+    { MODEPREFIX("1024x768"),   75000, 1024, 1048, 1184, 1328, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 70Hz */
+    { MODEPREFIX("1024x768"),   65000, 1024, 1048, 1184, 1344, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 60Hz */
+    { MODEPREFIX("1024x768"),   44900, 1024, 1032, 1208, 1264, 0,  768,  768,  776,  817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768 at 43Hz */
+    { MODEPREFIX("832x624"),    57284,  832,  864,  928, 1152, 0,  624,  625,  628,  667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624 at 75Hz */
+    { MODEPREFIX("800x600"),    49500,  800,  816,  896, 1056, 0,  600,  601,  604,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 75Hz */
+    { MODEPREFIX("800x600"),    50000,  800,  856,  976, 1040, 0,  600,  637,  643,  666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 72Hz */
+    { MODEPREFIX("1152x864"),  108000, 1152, 1216, 1344, 1600, 0,  864,  865,  868,  900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864 at 75Hz */
+};
+
+static DisplayModePtr
+DDCModesFromEstablished(int scrnIndex, struct established_timings *timing)
+{
+    DisplayModePtr Modes = NULL, Mode = NULL;
+    CARD32 bits = (timing->t1) | (timing->t2 << 8) |
+        ((timing->t_manu & 0x80) << 9);
+    int i;
+
+    for (i = 0; i < 17; i++) {
+        if (bits & (0x01 << i)) {
+            Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
+            Modes = xf86ModesAdd(Modes, Mode);
+        }
+    }
+
+    return Modes;
+}
+
+/*
+ *
+ */
+static DisplayModePtr
+DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing)
+{
+    DisplayModePtr Modes = NULL, Mode = NULL;
+    int i;
+    
+    for (i = 0; i < STD_TIMINGS; i++)
+        if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
+            Mode =  xf86CVTMode(timing[i].hsize, timing[i].vsize,
+                                timing[i].refresh, FALSE, FALSE);
+	    Mode->type = M_T_DRIVER;
+            Modes = xf86ModesAdd(Modes, Mode);
+        }
+
+    return Modes;
+}
+
+/*
+ *
+ */
+static DisplayModePtr
+DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
+			  int preferred)
+{
+    DisplayModePtr Mode;
+
+    /* We don't do stereo */
+    if (timing->stereo) {
+        xf86DrvMsg(scrnIndex, X_INFO, "%s: Ignoring: We don't handle stereo.\n",
+                   __func__);
+        return NULL;
+    }
+    
+    /* We only do seperate sync currently */
+    if (timing->sync != 0x03) {
+         xf86DrvMsg(scrnIndex, X_INFO, "%s: %dx%d Warning: We only handle seperate"
+                    " sync.\n", __func__, timing->h_active, timing->v_active);
+    }
+    
+    Mode = xnfalloc(sizeof(DisplayModeRec));
+    memset(Mode, 0, sizeof(DisplayModeRec));
+    
+    Mode->name = xnfalloc(10); /* "1234x1234" */
+    xf86snprintf(Mode->name, 20, "%dx%d", timing->h_active,
+                 timing->v_active);
+    
+    Mode->type = M_T_DRIVER;
+    if (preferred)
+	Mode->type |= M_T_PREFERRED;
+    
+    Mode->Clock = timing->clock / 1000.0;
+    
+    Mode->HDisplay = timing->h_active;
+    Mode->HSyncStart = timing->h_active + timing->h_sync_off;
+    Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
+    Mode->HTotal = timing->h_active + timing->h_blanking;
+    
+    Mode->VDisplay = timing->v_active;
+    Mode->VSyncStart = timing->v_active + timing->v_sync_off;
+    Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
+    Mode->VTotal = timing->v_active + timing->v_blanking;
+    
+    /* We ignore h/v_size and h/v_border for now. */
+    
+    if (timing->interlaced)
+        Mode->Flags |= V_INTERLACE;
+    
+    if (timing->misc & 0x02)
+        Mode->Flags |= V_PHSYNC;
+    else
+        Mode->Flags |= V_NHSYNC;
+    
+    if (timing->misc & 0x01)
+        Mode->Flags |= V_PVSYNC;
+    else
+        Mode->Flags |= V_NVSYNC;
+ 
+    return Mode;
+}
+
+/*
+ *
+ */
+static void
+DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
+{
+    DisplayModePtr Mode = Modes;
+
+    if (!Monitor || !Modes)
+        return;
+
+    /* set up the ranges for scanning through the modes */
+    Monitor->nHsync = 1;
+    Monitor->hsync[0].lo = 1024.0;
+    Monitor->hsync[0].hi = 0.0;
+
+    Monitor->nVrefresh = 1;
+    Monitor->vrefresh[0].lo = 1024.0;
+    Monitor->vrefresh[0].hi = 0.0;
+
+    while (Mode) {
+        if (!Mode->HSync)
+            Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
+
+        if (!Mode->VRefresh)
+            Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 
+                ((float) (Mode->HTotal * Mode->VTotal));
+
+        if (Mode->HSync < Monitor->hsync[0].lo)
+            Monitor->hsync[0].lo = Mode->HSync;
+
+        if (Mode->HSync > Monitor->hsync[0].hi)
+            Monitor->hsync[0].hi = Mode->HSync;
+
+        if (Mode->VRefresh < Monitor->vrefresh[0].lo)
+            Monitor->vrefresh[0].lo = Mode->VRefresh;
+
+        if (Mode->VRefresh > Monitor->vrefresh[0].hi)
+            Monitor->vrefresh[0].hi = Mode->VRefresh;
+        
+        Mode = Mode->next;
+    }
+}
+
+/*
+ * Fill out MonPtr with xf86MonPtr information.
+ */
+void
+xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
+{
+    DisplayModePtr Modes = NULL, Mode;
+    int i, clock;
+    Bool have_hsync = FALSE, have_vrefresh = FALSE;
+    int preferred;
+    
+    if (!Monitor || !DDC)
+        return;
+
+    Monitor->DDC = DDC;
+
+    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
+
+    Monitor->widthmm = 10 * DDC->features.hsize;
+    Monitor->heightmm = 10 * DDC->features.vsize;
+    
+    /* If this is a digital display, then we can use reduced blanking */
+    if (DDC->features.input_type) 
+        Monitor->reducedblanking = TRUE;
+    /* Allow the user to also enable this through config */
+
+    /* Add established timings */
+    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    /* Add standard timings */
+    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    /* Skip EDID ranges if they were specified in the config file */
+    have_hsync = (Monitor->nHsync != 0);
+    have_vrefresh = (Monitor->nVrefresh != 0);
+
+    /* Go through the detailed monitor sections */
+    for (i = 0; i < DET_TIMINGS; i++)
+        switch (DDC->det_mon[i].type) {
+        case DS_RANGES:
+	    if (!have_hsync) {
+		if (!Monitor->nHsync)
+		    xf86DrvMsg(scrnIndex, X_INFO,
+			    "Using EDID range info for horizontal sync\n");
+		Monitor->hsync[Monitor->nHsync].lo =
+		    DDC->det_mon[i].section.ranges.min_h;
+		Monitor->hsync[Monitor->nHsync].hi =
+		    DDC->det_mon[i].section.ranges.max_h;
+		Monitor->nHsync++;
+	    } else {
+		xf86DrvMsg(scrnIndex, X_INFO,
+			"Using hsync ranges from config file\n");
+	    }
+
+	    if (!have_vrefresh) {
+		if (!Monitor->nVrefresh)
+		    xf86DrvMsg(scrnIndex, X_INFO,
+			    "Using EDID range info for vertical refresh\n");
+		Monitor->vrefresh[Monitor->nVrefresh].lo =
+		    DDC->det_mon[i].section.ranges.min_v;
+		Monitor->vrefresh[Monitor->nVrefresh].hi =
+		    DDC->det_mon[i].section.ranges.max_v;
+		Monitor->nVrefresh++;
+	    } else {
+		xf86DrvMsg(scrnIndex, X_INFO,
+			"Using vrefresh ranges from config file\n");
+	    }
+
+	    clock = DDC->det_mon[i].section.ranges.max_clock * 1000;
+	    if (clock > Monitor->maxPixClock)
+		Monitor->maxPixClock = clock;
+
+            break;
+        case DT:
+            Mode = DDCModeFromDetailedTiming(scrnIndex, 
+                                             &DDC->det_mon[i].section.d_timings,
+					     preferred);
+	    preferred = 0;
+            Modes = xf86ModesAdd(Modes, Mode);
+            break;
+        case DS_STD_TIMINGS:
+            Mode = DDCModesFromStandardTiming(scrnIndex,
+                                             DDC->det_mon[i].section.std_t);
+            Modes = xf86ModesAdd(Modes, Mode);
+            break;
+        default:
+            break;
+        }
+
+    if (Modes) {
+        /* Print Modes */
+        xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n");
+
+        Mode = Modes;
+        while (Mode) {
+            xf86PrintModeline(scrnIndex, Mode);
+            Mode = Mode->next;
+        }
+
+        /* Do we still need ranges to be filled in? */
+        if (!Monitor->nHsync || !Monitor->nVrefresh)
+            DDCGuessRangesFromModes(scrnIndex, Monitor, Modes);
+
+        /* look for last Mode */
+        Mode = Modes;
+
+        while (Mode->next)
+            Mode = Mode->next;
+        
+        /* add to MonPtr */
+        if (Monitor->Modes) {
+            Monitor->Last->next = Modes;
+            Modes->prev = Monitor->Last;
+            Monitor->Last = Mode;
+        } else {
+            Monitor->Modes = Modes;
+            Monitor->Last = Mode;
+        }
+    }
+}
diff-tree 38ecc66cd9c61346a46697bbf1d8319f4f6f9800 (from 834e4b079866594b50be64ae79f3cb2a5baa2070)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Nov 28 10:06:15 2006 -0800

    Typo that was missed in testing.

diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c
index 87c91b8..ddf580c 100644
--- a/hw/xfree86/ddc/ddcProperty.c
+++ b/hw/xfree86/ddc/ddcProperty.c
@@ -69,7 +69,7 @@ DDCModesFromEstablished(int scrnIndex, s
 
     for (i = 0; i < 17; i++) {
         if (bits & (0x01 << i)) {
-            Mode = xf86DusplicateMode(&DDCEstablishedModes[i]);
+            Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
             Modes = xf86ModesAdd(Modes, Mode);
         }
     }



More information about the xorg-commit mailing list