xserver: Branch 'master'

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Thu Feb 12 15:47:24 PST 2009


 hw/xquartz/xpr/dri.c |   43 ++++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 17 deletions(-)

New commits:
commit d229ba7068f0adf1bc8b30b7ccf2fce2c7e8b97b
Author: George Staplin <gstaplin at apple.com>
Date:   Fri Feb 6 12:55:09 2009 -0700

    XQuartz: xpr: The dri.c code for pixmaps was wrong in several ways.  They weren't
    being exported correctly by Xplugin.
    
    This should fix a bug with the surface for a window, when an export fails.
    Before the export could fail and leave behind an invalid (freed) pointer in the dix privates.
    
    I have an idea of how to fix the GLXPixmaps now without using CGLSetOffScreen.
    
    This work is a step towards that.  The Xplugin will need a small patch to fix an
    issue that this change brought forth.
    (cherry picked from commit 58c4116c47543b5e30c2232e7bee8efc0b9be176)

diff --git a/hw/xquartz/xpr/dri.c b/hw/xquartz/xpr/dri.c
index ff2365e..59a4fdd 100644
--- a/hw/xquartz/xpr/dri.c
+++ b/hw/xquartz/xpr/dri.c
@@ -406,7 +406,7 @@ CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr)
     return pDRIDrawablePriv;
 }
 
-/* Return FALSE if an error occurs. */
+/* Return NULL if an error occurs. */
 static DRIDrawablePrivPtr
 CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
     DRIDrawablePrivPtr pDRIDrawablePriv;
@@ -415,7 +415,6 @@ CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
 
     if (pDRIDrawablePriv == NULL) {
 	xp_error err;
-	xp_window_changes wc;
 
 	/* allocate a DRI Window Private record */
 	if (!(pDRIDrawablePriv = xcalloc(1, sizeof(*pDRIDrawablePriv)))) {
@@ -437,18 +436,10 @@ CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
 	    return NULL;
 	}
 
-	wc.x = 0;
-        wc.y = 0;
-        wc.width = pPix->drawable.width;
-        wc.height = pPix->drawable.height;
-
-	err = xp_configure_surface(pDRIDrawablePriv->sid, XP_BOUNDS, &wc);
-
-	if(err != Success) {
-	    xp_destroy_surface(pDRIDrawablePriv->sid);
-	    xfree(pDRIDrawablePriv);
-	    return NULL;
-	}
+	/* 
+	 * The DRIUpdateSurface will be called to resize the surface
+	 * after this function, if the export is successful.
+	 */
 
 	/* save private off of preallocated index */
 	dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
@@ -489,21 +480,39 @@ DRICreateSurface(ScreenPtr pScreen, Drawable id,
         /* NOT_DONE */
         return FALSE;
     }
-
     
-
+    
     /* Finish initialization of new surfaces */
     if (pDRIDrawablePriv->refCount == 0) {
         unsigned int key[2] = {0};
         xp_error err;
 
         /* try to give the client access to the surface */
-        if (client_id != 0 && wid != 0) {
+        if (client_id != 0) {
+	    /*
+	     * Xplugin accepts a 0 wid if the surface id is offscreen, such 
+	     * as for a pixmap.
+	     */
             err = xp_export_surface(wid, pDRIDrawablePriv->sid,
                                     client_id, key);
             if (err != Success) {
                 xp_destroy_surface(pDRIDrawablePriv->sid);
                 xfree(pDRIDrawablePriv);
+		
+		/* 
+		 * Now set the dix privates to NULL that were previously set.
+		 * This prevents reusing an invalid pointer.
+		 */
+		if(pDrawable->type == DRAWABLE_WINDOW) {
+		    WindowPtr pWin = (WindowPtr)pDrawable;
+		    
+		    dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
+		} else if(pDrawable->type == DRAWABLE_PIXMAP) {
+		    PixmapPtr pPix = (PixmapPtr)pDrawable;
+		    
+		    dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
+		}
+		
                 return FALSE;
             }
         }


More information about the xorg-commit mailing list