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

Keith Packard keithp at kemper.freedesktop.org
Sun Mar 4 08:50:33 EET 2007


 hw/xfree86/modes/xf86Crtc.c    |   84 ++++++++++++++++++++++++++++-------------
 hw/xfree86/modes/xf86Crtc.h    |   26 +++++++++++-
 hw/xfree86/modes/xf86RandR12.c |   24 +++++++----
 randr/rrcrtc.c                 |   30 ++++++++++++++
 4 files changed, 128 insertions(+), 36 deletions(-)

New commits:
diff-tree 629515a159d49dfc11004bac32e9da747e595099 (from 1ce0c6877a2c1c2d7c78c7f496e91dd3493257eb)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Wed Feb 28 14:26:47 2007 -0800

    Add a canGrow argument to xf86InitialConfiguration.
    
    canGrow indicates to the DDX that the driver can enlarge the desktop via the
    xf86_config->funcs->resize hook.  If so, xf86InitialConfiguration will set
    virtual[XY] to match the configuration it chooses and will leave the crtc config
    size ranges alone.  If FALSE, it will bloat the screen to fit the largest probed
    mode and also set the crtc config max size to limit the desktop to the initial
    virtual[XY] size.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index ebc0f8f..c53d2a8 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -734,12 +734,16 @@ xf86PickCrtcs (ScrnInfoPtr	scrn,
 
 /*
  * Compute the virtual size necessary to place all of the available
- * crtcs in the specified configuration and also large enough to
- * resize any crtc to the largest available mode
+ * crtcs in the specified configuration.
+ *
+ * canGrow indicates that the driver can make the screen larger than its initial
+ * configuration.  If FALSE, this function will enlarge the screen to include
+ * the largest available mode.
  */
 
 static void
-xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp)
+xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp,
+			 Bool canGrow)
 {
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int	    width = 0, height = 0;
@@ -757,26 +761,28 @@ xf86DefaultScreenLimits (ScrnInfoPtr scr
 	    crtc_width = crtc->x + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation);
 	    crtc_height = crtc->y + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation);
 	}
-	for (o = 0; o < config->num_output; o++) 
-	{
-	    xf86OutputPtr   output = config->output[o];
+	if (!canGrow) {
+	    for (o = 0; o < config->num_output; o++)
+	    {
+		xf86OutputPtr   output = config->output[o];
 
-	    for (s = 0; s < config->num_crtc; s++)
-		if (output->possible_crtcs & (1 << s))
-		{
-		    DisplayModePtr  mode;
-		    for (mode = output->probed_modes; mode; mode = mode->next)
+		for (s = 0; s < config->num_crtc; s++)
+		    if (output->possible_crtcs & (1 << s))
 		    {
-			if (mode->HDisplay > crtc_width)
-			    crtc_width = mode->HDisplay;
-			if (mode->VDisplay > crtc_width)
-			    crtc_width = mode->VDisplay;
-			if (mode->VDisplay > crtc_height)
-			    crtc_height = mode->VDisplay;
-			if (mode->HDisplay > crtc_height)
-			    crtc_height = mode->HDisplay;
+			DisplayModePtr  mode;
+			for (mode = output->probed_modes; mode; mode = mode->next)
+			{
+			    if (mode->HDisplay > crtc_width)
+				crtc_width = mode->HDisplay;
+			    if (mode->VDisplay > crtc_width)
+				crtc_width = mode->VDisplay;
+			    if (mode->VDisplay > crtc_height)
+				crtc_height = mode->VDisplay;
+			    if (mode->HDisplay > crtc_height)
+				crtc_height = mode->HDisplay;
+			}
 		    }
-		}
+	    }
 	}
 	if (crtc_width > width)
 	    width = crtc_width;
@@ -1350,10 +1356,17 @@ xf86SetScrnInfoModes (ScrnInfoPtr scrn)
  *
  * Given auto-detected (and, eventually, configured) values,
  * construct a usable configuration for the system
+ *
+ * canGrow indicates that the driver can resize the screen to larger than its
+ * initially configured size via the config->funcs->resize hook.  If TRUE, this
+ * function will set virtualX and virtualY to match the initial configuration
+ * and leave config->max{Width,Height} alone.  If FALSE, it will bloat
+ * virtual[XY] to include the largest modes and set config->max{Width,Height}
+ * accordingly.
  */
 
 Bool
-xf86InitialConfiguration (ScrnInfoPtr	    scrn)
+xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
 {
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int			o, c;
@@ -1491,9 +1504,10 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     if (scrn->display->virtualX == 0)
     {
 	/*
-	 * Expand virtual size to cover potential mode switches
+	 * Expand virtual size to cover the current config and potential mode
+	 * switches, if the driver can't enlarge the screen later.
 	 */
-	xf86DefaultScreenLimits (scrn, &width, &height);
+	xf86DefaultScreenLimits (scrn, &width, &height, canGrow);
     
 	scrn->display->virtualX = width;
 	scrn->display->virtualY = height;
@@ -1503,7 +1517,23 @@ xf86InitialConfiguration (ScrnInfoPtr	  
 	scrn->virtualX = width;
     if (height > scrn->virtualY)
 	scrn->virtualY = height;
-    
+
+    /*
+     * Make sure the configuration isn't too small.
+     */
+    if (width < config->minWidth || height < config->minHeight)
+	return FALSE;
+
+    /*
+     * Limit the crtc config to virtual[XY] if the driver can't grow the
+     * desktop.
+     */
+    if (!canGrow)
+    {
+	xf86CrtcSetSizeRange (scrn, config->minWidth, config->minHeight,
+			      width, height);
+    }
+
     /* Mirror output modes to scrn mode list */
     xf86SetScrnInfoModes (scrn);
     
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 345332b..b04f7f3 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -545,7 +545,7 @@ void
 xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
 
 Bool
-xf86InitialConfiguration (ScrnInfoPtr pScrn);
+xf86InitialConfiguration (ScrnInfoPtr pScrn, Bool canGrow);
 
 void
 xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
diff-tree 1ce0c6877a2c1c2d7c78c7f496e91dd3493257eb (from 8a0a0d7db04c657c3b7e2e37f78f68f19d478983)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Wed Feb 28 13:36:58 2007 -0800

    Add a screen resize hook to xf86CrtcConfigRec.
    
    This hook is called when the DDX needs to resize the screen.  The driver is
    responsible for changing virtualX and virtualY, along with any other related
    screen properties (devPrivate.ptr, devKind, displayWidth, etc.).
    
    Use the size range from the crtc config instead of randrp->virtual[XY] when
    reporting the min and max screen sizes to the DDX.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 29042a0..ebc0f8f 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -52,13 +52,17 @@
 int xf86CrtcConfigPrivateIndex = -1;
 
 void
-xf86CrtcConfigInit (ScrnInfoPtr scrn)
+xf86CrtcConfigInit (ScrnInfoPtr scrn,
+		    const xf86CrtcConfigFuncsRec *funcs)
 {
     xf86CrtcConfigPtr	config;
     
     if (xf86CrtcConfigPrivateIndex == -1)
 	xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
     config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
+
+    config->funcs = funcs;
+
     scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
 }
  
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 756730e..345332b 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -407,6 +407,25 @@ struct _xf86Output {
 #endif
 };
 
+typedef struct _xf86CrtcConfigFuncs {
+    /**
+     * Requests that the driver resize the screen.
+     *
+     * The driver is responsible for updating scrn->virtualX and scrn->virtualY.
+     * If the requested size cannot be set, the driver should leave those values
+     * alone and return FALSE.
+     *
+     * A naive driver that cannot reallocate the screen may simply change
+     * virtual[XY].  A more advanced driver will want to also change the
+     * devPrivate.ptr and devKind of the screen pixmap, update any offscreen
+     * pixmaps it may have moved, and change pScrn->displayWidth.
+     */
+    Bool
+    (*resize)(ScrnInfoPtr	scrn,
+	      int		width,
+	      int		height);
+} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
+
 typedef struct _xf86CrtcConfig {
     int			num_output;
     xf86OutputPtr	*output;
@@ -435,6 +454,8 @@ typedef struct _xf86CrtcConfig {
     int			dga_width, dga_height, dga_stride;
     DisplayModePtr	dga_save_mode;
 
+    const xf86CrtcConfigFuncsRec *funcs;
+
 } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
 
 extern int xf86CrtcConfigPrivateIndex;
@@ -446,7 +467,8 @@ extern int xf86CrtcConfigPrivateIndex;
  */
 
 void
-xf86CrtcConfigInit (ScrnInfoPtr		scrn);
+xf86CrtcConfigInit (ScrnInfoPtr				scrn,
+		    const xf86CrtcConfigFuncsRec	*funcs);
 
 void
 xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 79580f0..1a349ef 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -335,8 +335,9 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScr
 {
     XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
     ScrnInfoPtr		pScrn = XF86SCRNINFO(pScreen);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
     WindowPtr		pRoot = WindowTable[pScreen->myNum];
-    Bool 		ret = TRUE;
+    Bool		ret = FALSE;
 
     if (randrp->virtualX == -1 || randrp->virtualY == -1)
     {
@@ -345,20 +346,26 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScr
     }
     if (pRoot)
 	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-    pScrn->virtualX = width;
-    pScrn->virtualY = height;
 
-    pScreen->width = pScrn->virtualX;
-    pScreen->height = pScrn->virtualY;
+    /* Let the driver update virtualX and virtualY */
+    if (!(*config->funcs->resize)(pScrn, width, height))
+	goto finish;
+
+    ret = TRUE;
+
+    pScreen->width = width;
+    pScreen->height = height;
     pScreen->mmWidth = mmWidth;
     pScreen->mmHeight = mmHeight;
 
     xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
     xf86SetViewport (pScreen, 0, 0);
+
+finish:
     if (pRoot)
 	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
 #if RANDR_12_INTERFACE
-    if (WindowTable[pScreen->myNum])
+    if (WindowTable[pScreen->myNum] && ret)
 	RRScreenSizeNotify (pScreen);
 #endif
     return ret;
@@ -1011,15 +1018,14 @@ xf86RandR12CreateScreenResources12 (Scre
 {
     int			c;
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
 
     for (c = 0; c < config->num_crtc; c++)
 	xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
     
     
-    RRScreenSetSizeRange (pScreen, 320, 240,
-			  randrp->virtualX, randrp->virtualY);
+    RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
+			  config->maxWidth, config->maxHeight);
     return TRUE;
 }
 
diff-tree 8a0a0d7db04c657c3b7e2e37f78f68f19d478983 (from 0104f5737bf16ad9cdf0cd3a0e20328c5364e8c7)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Wed Feb 28 16:09:11 2007 -0800

    Don't crash setting a NULL mode with a randr classic DDX. Also remember to update the screen size during modesets.

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 3cdf12c..43a6fca 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -299,6 +299,12 @@ RRCrtcSet (RRCrtcPtr    crtc,
 	    RRScreenRate	    rate;
 	    Bool		    ret;
 
+	    if (!mode)
+	    {
+		RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
+		return TRUE;
+	    }
+
 	    size.width = mode->mode.width;
 	    size.height = mode->mode.height;
 	    if (outputs[0]->mmWidth && outputs[0]->mmHeight)
@@ -319,7 +325,10 @@ RRCrtcSet (RRCrtcPtr    crtc,
 	     * 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
diff-tree 0104f5737bf16ad9cdf0cd3a0e20328c5364e8c7 (from aeabf2a1f873f884b8a8c33b1517c3f3cab4c7f5)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Mon Feb 26 17:45:40 2007 -0800

    Return BadMatch if a client tries to clone non-cloneable outputs.
    (cherry picked from commit 8b245758845523d5f8f017bb9d0e9aa57b616c28)

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index a90b072..3cdf12c 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -670,6 +670,27 @@ ProcRRSetCrtcConfig (ClientPtr client)
 	    return BadMatch;
 	}
     }
+    /* validate clones */
+    for (i = 0; i < numOutputs; i++)
+    {
+	for (j = 0; j < numOutputs; j++)
+	{
+	    int k;
+	    if (i == j)
+		continue;
+	    for (k = 0; k < outputs[i]->numClones; k++)
+	    {
+		if (outputs[i]->clones[k] == outputs[j])
+		    break;
+	    }
+	    if (k == outputs[i]->numClones)
+	    {
+		if (outputs)
+		    xfree (outputs);
+		return BadMatch;
+	    }
+	}
+    }
 
     pScreen = crtc->pScreen;
     pScrPriv = rrGetScrPriv(pScreen);



More information about the xorg-commit mailing list