xserver: Branch 'master' - 5 commits

Michel Daenzer daenzer at kemper.freedesktop.org
Mon Jun 11 00:33:03 PDT 2007


 GL/glx/glxdri.c            |   28 ++++++++++++++++++++++++++--
 dix/dixutils.c             |    2 +-
 hw/xfree86/dri/dri.c       |   30 ++++++++++++++++++++----------
 hw/xfree86/dri/drimodule.c |    2 +-
 hw/xfree86/dri/xf86dri.c   |   34 +++++++++++++++++++++++++++++++---
 mi/mieq.c                  |   22 ++++++----------------
 6 files changed, 85 insertions(+), 33 deletions(-)

New commits:
diff-tree 1aceec61ff203848576c47a1eab13f90a67d7176 (from 5d896e43fd056d935935b4eb66562791edc247a1)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jun 11 09:23:19 2007 +0200

    DRI: Clip cliprects obtained from DRIGetDrawableInfo to screen dimensions.
    
    This is to avoid issues with redirected windows which are located partly or
    fully outside of a screen edge, resulting in unusual cliprects which the 3D
    drivers generally can't handle. The symptoms in such cases would be incorrect
    rendering or even crashes or hangs.

diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 156e846..efa02f8 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -886,8 +886,32 @@ getDrawableInfo(__DRInativeDisplay *dpy,
     if (*numClipRects > 0) {
 	size = sizeof (drm_clip_rect_t) * *numClipRects;
 	*ppClipRects = xalloc (size);
-	if (*ppClipRects != NULL)
-	    memcpy (*ppClipRects, pClipRects, size);
+
+	/* Clip cliprects to screen dimensions (redirected windows) */
+	if (*ppClipRects != NULL) {
+	    ScreenPtr pScreen = screenInfo.screens[screen];
+	    int i, j;
+
+	    for (i = 0, j = 0; i < *numClipRects; i++) {
+	        (*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0);
+		(*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0);
+		(*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width);
+		(*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+		if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 &&
+		    (*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) {
+		    j++;
+		}
+	    }
+
+	    if (*numClipRects != j) {
+		*numClipRects = j;
+		*ppClipRects = xrealloc (*ppClipRects,
+					 sizeof (drm_clip_rect_t) *
+					 *numClipRects);
+	    }
+	} else
+	    *numClipRects = 0;
     }
     else {
       *ppClipRects = NULL;
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index d153c09..dbc1690 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -1518,13 +1518,18 @@ DRIGetDrawableInfo(ScreenPtr pScreen,
 	       if (x1 > pScreen->width) x1 = pScreen->width;
 	       if (y1 > pScreen->height) y1 = pScreen->height;
 
-	       pDRIPriv->private_buffer_rect.x1 = x0;
-	       pDRIPriv->private_buffer_rect.y1 = y0;
-	       pDRIPriv->private_buffer_rect.x2 = x1;
-	       pDRIPriv->private_buffer_rect.y2 = y1;
-
-	       *numBackClipRects = 1;
-	       *pBackClipRects = &(pDRIPriv->private_buffer_rect);
+	       if (y0 >= y1 || x0 >= x1) {
+		    *numBackClipRects = 0;
+		    *pBackClipRects = NULL;
+	       } else {
+		    pDRIPriv->private_buffer_rect.x1 = x0;
+		    pDRIPriv->private_buffer_rect.y1 = y0;
+		    pDRIPriv->private_buffer_rect.x2 = x1;
+		    pDRIPriv->private_buffer_rect.y2 = y1;
+
+		    *numBackClipRects = 1;
+		    *pBackClipRects = &(pDRIPriv->private_buffer_rect);
+	       }
 	    } else {
 	       /* Use the frontbuffer cliprects for back buffers.  */
 	       *numBackClipRects = 0;
diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c
index 933cd3e..9690e88 100644
--- a/hw/xfree86/dri/xf86dri.c
+++ b/hw/xfree86/dri/xf86dri.c
@@ -452,7 +452,7 @@ ProcXF86DRIGetDrawableInfo(
     xXF86DRIGetDrawableInfoReply	rep;
     DrawablePtr pDrawable;
     int X, Y, W, H;
-    drm_clip_rect_t * pClipRects;
+    drm_clip_rect_t * pClipRects, *pClippedRects;
     drm_clip_rect_t * pBackClipRects;
     int backX, backY, rc;
 
@@ -502,8 +502,35 @@ ProcXF86DRIGetDrawableInfo(
     if (rep.numBackClipRects) 
        rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;    
 
-    if (rep.numClipRects) 
+    pClippedRects = pClipRects;
+
+    if (rep.numClipRects) {
+       /* Clip cliprects to screen dimensions (redirected windows) */
+       pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
+
+       if (pClippedRects) {
+	    ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+	    int i, j;
+
+	    for (i = 0, j = 0; i < rep.numClipRects; i++) {
+		pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
+		pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
+		pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
+		pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+		if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
+		    pClippedRects[j].y1 < pClippedRects[j].y2) {
+		    j++;
+		}
+	    }
+
+	    rep.numClipRects = j;
+       } else {
+	    rep.numClipRects = 0;
+       }
+
        rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+    }
     
     rep.length = ((rep.length + 3) & ~3) >> 2;
 
@@ -512,7 +539,8 @@ ProcXF86DRIGetDrawableInfo(
     if (rep.numClipRects) {
 	WriteToClient(client,  
 		      sizeof(drm_clip_rect_t) * rep.numClipRects,
-		      (char *)pClipRects);
+		      (char *)pClippedRects);
+	xfree(pClippedRects);
     }
 
     if (rep.numBackClipRects) {
diff-tree 5d896e43fd056d935935b4eb66562791edc247a1 (from 0fb44c6f9a0415184818ba8357a21ff920e907dc)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jun 11 09:23:19 2007 +0200

    DRITreeTraversal: Stop walking tree when we've seen all DRI windows.

diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index fae0b43..d153c09 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -1863,11 +1863,15 @@ DRITreeTraversal(WindowPtr pWin, pointer
     if(pDRIDrawablePriv) {
         ScreenPtr pScreen = pWin->drawable.pScreen;
         DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-        RegionPtr reg = (RegionPtr)data;
 
-        REGION_UNION(pScreen, reg, reg, &(pWin->clipList));
+	if(REGION_NUM_RECTS(&(pWin->clipList)) > 0) {
+	   RegionPtr reg = (RegionPtr)data;
 
-        if(pDRIPriv->nrWindows == 1)
+	   REGION_UNION(pScreen, reg, reg, &(pWin->clipList));
+	   pDRIPriv->nrWalked++;
+	}
+
+	if(pDRIPriv->nrWindows == pDRIPriv->nrWalked)
 	   return WT_STOPWALKING;
     }
     return WT_WALKCHILDREN;
@@ -1885,6 +1889,7 @@ DRICopyWindow(WindowPtr pWin, DDXPointRe
        RegionRec reg;
 
        REGION_NULL(pScreen, &reg);
+       pDRIPriv->nrWalked = 0;
        TraverseTree(pWin, DRITreeTraversal, (pointer)(&reg));
 
        if(REGION_NOTEMPTY(pScreen, &reg)) {
diff-tree 0fb44c6f9a0415184818ba8357a21ff920e907dc (from 644f7ddc0cb029e2ebca43742fd8a46a1a3f4c9f)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jun 11 09:23:19 2007 +0200

    DRI: Fix build warning.

diff --git a/hw/xfree86/dri/drimodule.c b/hw/xfree86/dri/drimodule.c
index 0e3d84e..3aa9245 100644
--- a/hw/xfree86/dri/drimodule.c
+++ b/hw/xfree86/dri/drimodule.c
@@ -88,6 +88,6 @@ driSetup(pointer module, pointer opts, i
     drmSetServerInfo(&DRIDRMServerInfo);
 
     /* Need a non-NULL return value to indicate success */
-    return 1;
+    return (pointer)1;
 }
 
diff-tree 644f7ddc0cb029e2ebca43742fd8a46a1a3f4c9f (from 30a3297fed9af3a594aba0875a8f58a0a38b33fc)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jun 11 09:23:18 2007 +0200

    dixLookupClient: Use access parameter.

diff --git a/dix/dixutils.c b/dix/dixutils.c
index 30327d3..c1e30ff 100644
--- a/dix/dixutils.c
+++ b/dix/dixutils.c
@@ -265,7 +265,7 @@ _X_EXPORT int
 dixLookupClient(ClientPtr *pClient, XID rid, ClientPtr client, Mask access)
 {
     pointer pRes = (pointer)SecurityLookupIDByClass(client, rid, RC_ANY,
-						    DixReadAccess);
+						    access);
     int clientIndex = CLIENT_ID(rid);
     client->errorValue = rid;
 
diff-tree 30a3297fed9af3a594aba0875a8f58a0a38b33fc (from c1a49a9269f14b6975a1a2c751bb179757373f11)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jun 11 09:23:18 2007 +0200

    mieq queue handling cleanups.
    
    In particular, fix handling of wraparounds in mieqEnqueue.

diff --git a/mi/mieq.c b/mi/mieq.c
index a03fff1..f64e540 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -108,7 +108,8 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e
     HWEventQueueType       oldtail = miEventQueue.tail, newtail;
     int                    isMotion = 0;
     deviceValuator         *v = (deviceValuator *) e;
-    EventPtr               laste = &miEventQueue.events[oldtail - 1];
+    EventPtr               laste = &miEventQueue.events[(oldtail - 1) %
+							QUEUE_SIZE];
     deviceKeyButtonPointer *lastkbp = (deviceKeyButtonPointer *)
                                       &laste->event[0];
 
@@ -139,14 +140,10 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e
 
     if (isMotion && isMotion == miEventQueue.lastMotion &&
         oldtail != miEventQueue.head) {
-	if (oldtail == 0)
-	    oldtail = QUEUE_SIZE;
-	oldtail = oldtail - 1;
+	oldtail = (oldtail - 1) % QUEUE_SIZE;
     }
     else {
-    	newtail = oldtail + 1;
-    	if (newtail == QUEUE_SIZE)
-	    newtail = 0;
+    	newtail = (oldtail + 1) % QUEUE_SIZE;
     	/* Toss events which come in late.  Usually this means your server's
          * stuck in an infinite loop somewhere, but SIGIO is still getting
          * handled. */
@@ -214,22 +211,15 @@ mieqProcessInputEvents(void)
 
         e = &miEventQueue.events[miEventQueue.head];
         /* Assumption - screen switching can only occur on motion events. */
+        miEventQueue.head = (miEventQueue.head + 1) % QUEUE_SIZE;
+
         if (e->pScreen != miEventQueue.pDequeueScreen) {
             miEventQueue.pDequeueScreen = e->pScreen;
             x = e->event[0].u.keyButtonPointer.rootX;
             y = e->event[0].u.keyButtonPointer.rootY;
-            if (miEventQueue.head == QUEUE_SIZE - 1)
-                miEventQueue.head = 0;
-            else
-                ++miEventQueue.head;
             NewCurrentScreen (miEventQueue.pDequeueScreen, x, y);
         }
         else {
-            if (miEventQueue.head == QUEUE_SIZE - 1)
-                miEventQueue.head = 0;
-            else
-                ++miEventQueue.head;
-
             /* If someone's registered a custom event handler, let them
              * steal it. */
             if (miEventQueue.handlers[e->event->u.u.type]) {


More information about the xorg-commit mailing list