xserver: Branch 'master' - 6 commits

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


 hw/xfree86/loader/xf86sym.c   |    1 
 hw/xfree86/modes/xf86Crtc.c   |   36 +++++++++-
 hw/xfree86/modes/xf86Crtc.h   |    8 ++
 hw/xfree86/modes/xf86Rotate.c |   68 +++++++++++++-----
 randr/randr.c                 |    2 
 randr/randrstr.h              |    5 +
 randr/rrcrtc.c                |   91 +++++++++++++------------
 randr/rrproperty.c            |  151 +++++++++++++++++++++++++-----------------
 8 files changed, 241 insertions(+), 121 deletions(-)

New commits:
diff-tree 476f2b5aefa518262b69e487555e6094818d857a (from 7093367c3976bef5b9d219d9f2a7dc7dd3eeb091)
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.
    (cherry picked from commit 945aa0aa556429b50dea8e8ebc0008304b093eb7)

diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index b0182da..148e4a2 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 7093367c3976bef5b9d219d9f2a7dc7dd3eeb091 (from 86d76390eb182f271f5fa5dc19205e97a867f7e7)
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.
    (cherry picked from commit 8eb288fbd69e2ffd02521d2c6a964c8180d08ec8)

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 0dee999..9f039f7 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -761,10 +761,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 edfed1f..b0182da 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) {
-	/* 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 86d76390eb182f271f5fa5dc19205e97a867f7e7 (from 510eaa346e68fd82c852c7b41fb0e2c5be12da78)
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.
    (cherry picked from commit 9ca7ba5d6012295a77ed773c656e786440da973d)

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index ecf5bb2..7131dfb 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -262,6 +262,8 @@ RRCrtcSet (RRCrtcPtr    crtc,
 	   RROutputPtr  *outputs)
 {
     ScreenPtr	pScreen = crtc->pScreen;
+    Bool	ret = FALSE;
+    rrScrPriv(pScreen);
 
     /* See if nothing changed */
     if (crtc->mode == mode &&
@@ -271,61 +273,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;
 }
 
 /*
@@ -718,6 +723,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
@@ -728,6 +734,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
 	rep.status = RRSetConfigInvalidConfigTime;
 	goto sendReply;
     }
+#endif
     
     /*
      * Validate requested rotation
diff-tree 510eaa346e68fd82c852c7b41fb0e2c5be12da78 (from 479b2be4badab0a67b1f091feb83c1364e27d783)
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.
    (cherry picked from commit 492c768065f49306a2194a88edf96b85de0ff4ff)

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 479b2be4badab0a67b1f091feb83c1364e27d783 (from b63e0d2545bb75e14d9de019a88f31e20a2f7377)
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.
    (cherry picked from commit 16f4c0c1750824f2e5a001cef82a4122a7a2beb0)

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;
 
diff-tree b63e0d2545bb75e14d9de019a88f31e20a2f7377 (from 3e9f7a5504ab41d845e88f293d8498c963d8a7d8)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Tue Mar 20 07:17:27 2007 -0700

    Clean up Rotate state on server reset.
    
    The rotation state is stored in the xf86_config structure which is not
    re-initialized at server reset time. Clean it up at CloseScreen time.
    (cherry picked from commit f8db7665dcd7af78ca4db2461e0bf787ec662cb1)

diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c
index bc7c814..5175f01 100644
--- a/hw/xfree86/loader/xf86sym.c
+++ b/hw/xfree86/loader/xf86sym.c
@@ -1170,6 +1170,7 @@ _X_HIDDEN void *xfree86LookupTab[] = {
     SYMVAR(pciNumBuses)
 
     /* modes */
+    SYMVAR(xf86CrtcConfigPrivateIndex)
     SYMFUNC(xf86CrtcConfigInit)
     SYMFUNC(xf86CrtcConfigPrivateIndex)
     SYMFUNC(xf86CrtcCreate)
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 1a42920..a875cdf 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -566,6 +566,22 @@ xf86CrtcCreateScreenResources (ScreenPtr
 }
 
 /*
+ * Clean up config on server reset
+ */
+static Bool
+xf86CrtcCloseScreen (int index, ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    
+    screen->CloseScreen = config->CloseScreen;
+
+    xf86RotateCloseScreen (screen);
+
+    return screen->CloseScreen (index, screen);
+}
+
+/*
  * Called at ScreenInit time to set up
  */
 Bool
@@ -596,6 +612,10 @@ xf86CrtcScreenInit (ScreenPtr screen)
     /* Wrap CreateScreenResources so we can initialize the RandR code */
     config->CreateScreenResources = screen->CreateScreenResources;
     screen->CreateScreenResources = xf86CrtcCreateScreenResources;
+
+    config->CloseScreen = screen->CloseScreen;
+    screen->CloseScreen = xf86CrtcCloseScreen;
+    
     return TRUE;
 }
 
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index b751592..42daf60 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -544,6 +544,8 @@ typedef struct _xf86CrtcConfig {
 
     CreateScreenResourcesProcPtr    CreateScreenResources;
 
+    CloseScreenProcPtr		    CloseScreen;
+
     /* Cursor information */
     xf86CursorInfoPtr	cursor_info;
     CursorPtr		cursor;
@@ -593,6 +595,12 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, Displ
 Bool
 xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
 
+/*
+ * Clean up rotation during CloseScreen
+ */
+void
+xf86RotateCloseScreen (ScreenPtr pScreen);
+
 /**
  * Return whether any output is assigned to the crtc
  */
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index e82b69e..e8fafd0 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -321,36 +321,68 @@ xf86RotateWakeupHandler(pointer data, in
 {
 }
 
-Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
+static void
+xf86RotateDestroy (xf86CrtcPtr crtc)
 {
     ScrnInfoPtr		pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     ScreenPtr		pScreen = pScrn->pScreen;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			c;
     
-    if (rotation == RR_Rotate_0)
+    /* Free memory from rotation */
+    if (crtc->rotatedPixmap || crtc->rotatedData)
     {
-	/* Free memory from rotation */
+	crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
+	crtc->rotatedPixmap = NULL;
+	crtc->rotatedData = NULL;
+    }
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
 	if (crtc->rotatedPixmap || crtc->rotatedData)
-	{
-	    crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
-	    crtc->rotatedPixmap = NULL;
-	    crtc->rotatedData = NULL;
-	}
+	    return;
 
-	if (xf86_config->rotation_damage)
+    /*
+     * Clean up damage structures when no crtcs are rotated
+     */
+    if (xf86_config->rotation_damage)
+    {
+	/* Free damage structure */
+	if (xf86_config->rotation_damage_registered)
 	{
-	    /* Free damage structure */
 	    DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
 			      xf86_config->rotation_damage);
 	    xf86_config->rotation_damage_registered = FALSE;
-	    DamageDestroy (xf86_config->rotation_damage);
-	    xf86_config->rotation_damage = NULL;
-	    /* Free block/wakeup handler */
-	    RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
-					  xf86RotateWakeupHandler,
-					  (pointer) pScreen);
 	}
+	DamageDestroy (xf86_config->rotation_damage);
+	xf86_config->rotation_damage = NULL;
+	/* Free block/wakeup handler */
+	RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
+				      xf86RotateWakeupHandler,
+				      (pointer) pScreen);
+    }
+}
+
+void
+xf86RotateCloseScreen (ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+	xf86RotateDestroy (xf86_config->crtc[c]);
+}
+
+Bool
+xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
+{
+    ScrnInfoPtr		pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    ScreenPtr		pScreen = pScrn->pScreen;
+    
+    if (rotation == RR_Rotate_0)
+    {
+	xf86RotateDestroy (crtc);
     }
     else
     {



More information about the xorg-commit mailing list