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, ®);
+ pDRIPriv->nrWalked = 0;
TraverseTree(pWin, DRITreeTraversal, (pointer)(®));
if(REGION_NOTEMPTY(pScreen, ®)) {
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