xserver: Branch 'server-1.3-branch' - 5 commits

Keith Packard keithp at kemper.freedesktop.org
Fri Mar 23 10:27:10 EET 2007


 hw/xfree86/modes/xf86Crtc.c |   16 ++++
 randr/randr.c               |    2 
 randr/randrstr.h            |    5 +
 randr/rrcrtc.c              |   91 ++++++++++++++------------
 randr/rrproperty.c          |  151 +++++++++++++++++++++++++++-----------------
 5 files changed, 162 insertions(+), 103 deletions(-)

New commits:
diff-tree 945aa0aa556429b50dea8e8ebc0008304b093eb7 (from 8eb288fbd69e2ffd02521d2c6a964c8180d08ec8)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Fri Mar 23 01:17:14 2007 -0700

    Incorrect extra memory copy in RRChangeOutputProperty.
    
    Left over from previous version of the code, this memmove will break when
    the mode is not Replace.

diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index a57bd74..afac351 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -177,8 +177,6 @@ RRChangeOutputProperty (RROutputPtr outp
 		RRDestroyOutputProperty (prop);
 	    return BadAlloc;
 	}
-	if (len)
-	    memmove((char *)new_value.data, (char *)value, total_size);
 	new_value.size = len;
 	new_value.type = type;
 	new_value.format = format;
diff-tree 8eb288fbd69e2ffd02521d2c6a964c8180d08ec8 (from 9ca7ba5d6012295a77ed773c656e786440da973d)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Fri Mar 23 01:05:55 2007 -0700

    Fix Pending property API, adding RRPostPendingProperty.
    
    Pending Properties take effect when the driver says they do, so provide an
    API to tell DIX when a property effect is made. Also, allow driver
    to reject property values in RRChangeOutputProperty.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index fad0752..2341715 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1923,7 +1923,7 @@ xf86OutputSetEDIDProperty (xf86OutputPtr
 
     if (data_len != 0) {
 	RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
-			       PropModeReplace, data_len, data, FALSE);
+			       PropModeReplace, data_len, data, FALSE, TRUE);
     } else {
 	RRDeleteOutputProperty(output->randr_output, edid_atom);
     }
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 3968103..40d3eec 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -759,10 +759,13 @@ RRQueryOutputProperty (RROutputPtr outpu
 void
 RRDeleteOutputProperty (RROutputPtr output, Atom property);
 
+Bool
+RRPostPendingProperty (RROutputPtr output, Atom property);
+    
 int
 RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
 			int format, int mode, unsigned long len,
-			pointer value, Bool sendevent);
+			pointer value, Bool sendevent, Bool pending);
 
 int
 RRConfigureOutputProperty (RROutputPtr output, Atom property,
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index e020d5b..a57bd74 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -121,19 +121,19 @@ RRDeleteOutputProperty (RROutputPtr outp
 int
 RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
 			int format, int mode, unsigned long len,
-			pointer value, Bool sendevent)
+			pointer value, Bool sendevent, Bool pending)
 {
     RRPropertyPtr		    prop;
     xRROutputPropertyNotifyEvent    event;
     rrScrPrivPtr		    pScrPriv = rrGetScrPriv(output->pScreen);
-    int				    sizeInBytes;
-    int				    totalSize;
-    pointer			    data;
+    int				    size_in_bytes;
+    int				    total_size;
+    unsigned long		    total_len;
     RRPropertyValuePtr		    prop_value;
+    RRPropertyValueRec		    new_value;
     Bool			    add = FALSE;
 
-    sizeInBytes = format >> 3;
-    totalSize = len * sizeInBytes;
+    size_in_bytes = format >> 3;
 
     /* first see if property already exists */
     prop = RRQueryOutputProperty (output, property);
@@ -145,7 +145,7 @@ RRChangeOutputProperty (RROutputPtr outp
 	add = TRUE;
 	mode = PropModeReplace;
     }
-    if (prop->is_pending)
+    if (pending && prop->is_pending)
 	prop_value = &prop->pending;
     else
 	prop_value = &prop->current;
@@ -159,68 +159,75 @@ RRChangeOutputProperty (RROutputPtr outp
 	return(BadMatch);
     if ((prop_value->type != type) && (mode != PropModeReplace))
 	return(BadMatch);
+    new_value = *prop_value;
     if (mode == PropModeReplace)
+	total_len = len;
+    else
+	total_len = prop_value->size + len;
+
+    if (mode == PropModeReplace || len > 0)
     {
-	if (totalSize != prop_value->size * (prop_value->format >> 3))
+	pointer	    new_data, old_data;
+	
+	total_size = total_len * size_in_bytes;
+	new_value.data = (pointer)xalloc (total_size);
+	if (!new_value.data && total_size)
 	{
-	    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);
-	    }
-	    prop_value->data = data;
+	    if (add)
+		RRDestroyOutputProperty (prop);
+	    return BadAlloc;
 	}
 	if (len)
-	    memmove((char *)prop_value->data, (char *)value, totalSize);
-	prop_value->size = len;
-	prop_value->type = type;
-	prop_value->format = format;
+	    memmove((char *)new_value.data, (char *)value, total_size);
+	new_value.size = len;
+	new_value.type = type;
+	new_value.format = format;
+
+	switch (mode) {
+	case PropModeReplace:
+	    new_data = new_value.data;
+	    old_data = NULL;
+	    break;
+	case PropModeAppend:
+	    new_data = (pointer) (((char *) new_value.data) + 
+				  (prop_value->size * size_in_bytes));
+	    old_data = new_value.data;
+	    break;
+	case PropModePrepend:
+	    new_data = new_value.data;
+	    old_data = (pointer) (((char *) new_value.data) + 
+				  (prop_value->size * size_in_bytes));
+	    break;
+	}
+	memcpy ((char *) new_data, (char *) value, len * size_in_bytes);
+	if (old_data)
+	    memcpy ((char *) old_data, (char *) prop_value->data, 
+		    prop_value->size * size_in_bytes);
+	
+	if (pending && pScrPriv->rrOutputSetProperty &&
+	    !pScrPriv->rrOutputSetProperty(output->pScreen, output,
+					   prop->propertyName, &new_value))
+	{
+	    if (new_value.data)
+		xfree (new_value.data);
+	    return (BadValue);
+	}
+	if (prop_value->data)
+	    xfree (prop_value->data);
+	*prop_value = new_value;
     }
+    
     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 (!prop->is_pending && pScrPriv->rrOutputSetProperty) {
-	/* What should we do in case of failure? */
-	pScrPriv->rrOutputSetProperty(output->pScreen, output,
-				      prop->propertyName, prop_value);
-    }
-
     if (sendevent)
     {
 	event.type = RREventBase + RRNotify;
@@ -234,6 +241,33 @@ RRChangeOutputProperty (RROutputPtr outp
     return(Success);
 }
 
+Bool
+RRPostPendingProperty (RROutputPtr output, Atom property)
+{
+    RRPropertyPtr		    prop = RRQueryOutputProperty (output, property);
+    RRPropertyValuePtr		    pending_value;
+    RRPropertyValuePtr		    current_value;
+    
+    if (!prop)
+	return FALSE;
+    if (!prop->is_pending)
+	return FALSE;
+    pending_value = &prop->pending;
+    current_value = &prop->current;
+
+    if (pending_value->type == current_value->type &&
+	pending_value->format == current_value->format &&
+	pending_value->size == current_value->size &&
+	!memcmp (pending_value->data, current_value->data, pending_value->size))
+	return TRUE;
+    
+    if (RRChangeOutputProperty (output, property, 
+				pending_value->type, pending_value->format, PropModeReplace,
+				pending_value->size, pending_value->data, TRUE, FALSE) != Success)
+	return FALSE;
+    return TRUE;
+}
+
 RRPropertyPtr
 RRQueryOutputProperty (RROutputPtr output, Atom property)
 {
@@ -474,7 +508,7 @@ ProcRRChangeOutputProperty (ClientPtr cl
 
     err = RRChangeOutputProperty(output, stuff->property,
 				 stuff->type, (int)format,
-				 (int)mode, len, (pointer)&stuff[1], TRUE);
+				 (int)mode, len, (pointer)&stuff[1], TRUE, TRUE);
     if (err != Success)
 	return err;
     else
@@ -508,8 +542,8 @@ int
 ProcRRGetOutputProperty (ClientPtr client)
 {
     REQUEST(xRRGetOutputPropertyReq);
-    RRPropertyPtr			prop, *prev;
-    RRPropertyValuePtr			prop_value;
+    RRPropertyPtr		prop, *prev;
+    RRPropertyValuePtr		prop_value;
     unsigned long		n, len, ind;
     RROutputPtr			output;
     xRRGetOutputPropertyReply	reply;
@@ -600,7 +634,10 @@ ProcRRGetOutputProperty (ClientPtr clien
     reply.bytesAfter = n - (ind + len);
     reply.format = prop_value->format;
     reply.length = (len + 3) >> 2;
-    reply.nItems = len / (prop_value->format / 8 );
+    if (prop_value->format)
+	reply.nItems = len / (prop_value->format / 8);
+    else
+	reply.nItems = 0;
     reply.propertyType = prop_value->type;
 
     if (stuff->delete && (reply.bytesAfter == 0))
diff-tree 9ca7ba5d6012295a77ed773c656e786440da973d (from 492c768065f49306a2194a88edf96b85de0ff4ff)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Fri Mar 23 01:03:40 2007 -0700

    Make sure RandR events are delivered from RRCrtcSet.
    
    Some paths were skipping the event delivery stage.

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 1b3c230..da88253 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -271,6 +271,8 @@ RRCrtcSet (RRCrtcPtr    crtc,
 	   RROutputPtr  *outputs)
 {
     ScreenPtr	pScreen = crtc->pScreen;
+    Bool	ret = FALSE;
+    rrScrPriv(pScreen);
 
     /* See if nothing changed */
     if (crtc->mode == mode &&
@@ -280,61 +282,64 @@ RRCrtcSet (RRCrtcPtr    crtc,
 	crtc->numOutputs == numOutputs &&
 	!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)))
     {
-	return TRUE;
+	ret = TRUE;
     }
-    if (pScreen)
+    else
     {
 #if RANDR_12_INTERFACE
-	rrScrPriv(pScreen);
 	if (pScrPriv->rrCrtcSet)
 	{
-	    return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, 
-					   rotation, numOutputs, outputs);
+	    ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, 
+					  rotation, numOutputs, outputs);
 	}
+	else
 #endif
-#if RANDR_10_INTERFACE
-	if (pScrPriv->rrSetConfig)
 	{
-	    RRScreenSize	    size;
-	    RRScreenRate	    rate;
-	    Bool		    ret;
-
-	    if (!mode)
+#if RANDR_10_INTERFACE
+	    if (pScrPriv->rrSetConfig)
 	    {
-		RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
-		return TRUE;
-	    }
+		RRScreenSize	    size;
+		RRScreenRate	    rate;
 
-	    size.width = mode->mode.width;
-	    size.height = mode->mode.height;
-	    if (outputs[0]->mmWidth && outputs[0]->mmHeight)
-	    {
-		size.mmWidth = outputs[0]->mmWidth;
-		size.mmHeight = outputs[0]->mmHeight;
+		if (!mode)
+		{
+		    RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
+		    ret = TRUE;
+		}
+		else
+		{
+		    size.width = mode->mode.width;
+		    size.height = mode->mode.height;
+		    if (outputs[0]->mmWidth && outputs[0]->mmHeight)
+		    {
+			size.mmWidth = outputs[0]->mmWidth;
+			size.mmHeight = outputs[0]->mmHeight;
+		    }
+		    else
+		    {
+			size.mmWidth = pScreen->mmWidth;
+			size.mmHeight = pScreen->mmHeight;
+		    }
+		    size.nRates = 1;
+		    rate.rate = RRVerticalRefresh (&mode->mode);
+		    size.pRates = &rate;
+		    ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
+		    /*
+		     * Old 1.0 interface tied screen size to mode size
+		     */
+		    if (ret)
+		    {
+			RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
+			RRScreenSizeNotify (pScreen);
+		    }
+		}
 	    }
-	    else
-	    {
-		size.mmWidth = pScreen->mmWidth;
-		size.mmHeight = pScreen->mmHeight;
-	    }
-	    size.nRates = 1;
-	    rate.rate = RRVerticalRefresh (&mode->mode);
-	    size.pRates = &rate;
-	    ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
-	    /*
-	     * Old 1.0 interface tied screen size to mode size
-	     */
-	    if (ret)
-	    {
-		RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
-		RRScreenSizeNotify (pScreen);
-	    }
-	    return ret;
-	}
 #endif
-	RRTellChanged (pScreen);
+	}
+	if (ret)
+	    RRTellChanged (pScreen);
     }
-    return FALSE;
+    return ret;
 }
 
 /*
@@ -716,6 +721,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
 	goto sendReply;
     }
     
+#if 0
     /*
      * if the client's config timestamp is not the same as the last config
      * timestamp, then the config information isn't up-to-date and
@@ -726,6 +732,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
 	rep.status = RRSetConfigInvalidConfigTime;
 	goto sendReply;
     }
+#endif
     
     /*
      * Validate requested rotation
diff-tree 492c768065f49306a2194a88edf96b85de0ff4ff (from 16f4c0c1750824f2e5a001cef82a4122a7a2beb0)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Fri Mar 23 00:59:11 2007 -0700

    Clean up xf86CrtcRec and xf86OutputRec objects at CloseScreen.
    
    Erase pointers to structures which are freed at server reset time.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index a875cdf..fad0752 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -573,11 +573,25 @@ xf86CrtcCloseScreen (int index, ScreenPt
 {
     ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o, c;
     
     screen->CloseScreen = config->CloseScreen;
 
     xf86RotateCloseScreen (screen);
 
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	output->crtc = NULL;
+	output->randr_output = NULL;
+    }
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86CrtcPtr	crtc = config->crtc[c];
+
+	crtc->randr_crtc = NULL;
+    }
     return screen->CloseScreen (index, screen);
 }
 
diff-tree 16f4c0c1750824f2e5a001cef82a4122a7a2beb0 (from f8db7665dcd7af78ca4db2461e0bf787ec662cb1)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Fri Mar 23 00:57:18 2007 -0700

    Clear allocated RandR screen private structure.
    
    Use xcalloc instead of xalloc when allocating this structure to ensure
    consistent contents at startup.

diff --git a/randr/randr.c b/randr/randr.c
index 5fa9baf..4dd0ee5 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -230,7 +230,7 @@ Bool RRScreenInit(ScreenPtr pScreen)
 	RRScreenGeneration = serverGeneration;
     }
 
-    pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
+    pScrPriv = (rrScrPrivPtr) xcalloc (1, sizeof (rrScrPrivRec));
     if (!pScrPriv)
 	return FALSE;
 



More information about the xorg-commit mailing list