summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xfree86/dri2/dri2.c43
-rw-r--r--hw/xfree86/dri2/dri2.h4
-rw-r--r--hw/xfree86/dri2/dri2ext.c6
3 files changed, 35 insertions, 18 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 9f262aeef..30e36e8ca 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -238,6 +238,26 @@ DRI2LookupClientDrawableRef(DRI2DrawablePtr pPriv, ClientPtr client, XID id)
return NULL;
}
+static Bool
+DRI2MatchDrawableRef(pointer data, XID fake_id, pointer cdata)
+{
+ DRI2DrawablePtr pPriv = data;
+ XID id = (XID)cdata;
+ DRI2DrawableRefPtr ref = DRI2LookupDrawableRef(pPriv, id);
+ return ref != NULL;
+}
+
+int
+DRI2LookupDrawableComplex(ClientPtr client, XID id, DRI2DrawablePtr *pPriv)
+{
+ DRI2DrawablePtr tmp = LookupClientResourceComplex(client, dri2DrawableRes,
+ DRI2MatchDrawableRef, (pointer)id);
+ if (!tmp)
+ return BadDrawable;
+ *pPriv = tmp;
+ return Success;
+}
+
static int
DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id,
DRI2InvalidateProcPtr invalidate, void *priv)
@@ -307,9 +327,7 @@ static int DRI2DrawableGone(pointer p, XID id)
DRI2DrawablePtr pPriv = p;
DRI2ScreenPtr ds = pPriv->dri2_screen;
DRI2DrawableRefPtr ref, next;
- WindowPtr pWin;
- PixmapPtr pPixmap;
- DrawablePtr pDraw;
+ DrawablePtr pDraw = pPriv->drawable;
int i;
list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
@@ -324,11 +342,10 @@ static int DRI2DrawableGone(pointer p, XID id)
break;
}
- if (ref->id == id) {
- pPriv->refcnt--;
- list_del(&ref->link);
- FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE);
- free(ref);
+ if (ref->id == id && pDraw && pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr) pDraw;
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+ pPriv->drawable = NULL;
}
}
@@ -336,13 +353,11 @@ static int DRI2DrawableGone(pointer p, XID id)
if (pPriv->refcnt > 0)
return Success;
- pDraw = pPriv->drawable;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr) pDraw;
+ if (pDraw && pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr) pDraw;
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
- } else {
- pPixmap = (PixmapPtr) pDraw;
+ } else if (pDraw) {
+ PixmapPtr pPixmap = (PixmapPtr) pDraw;
dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
pDraw->pScreen->DestroyPixmap(pPixmap);
}
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 2c11e6bd6..071fe4c2b 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -321,4 +321,8 @@ extern _X_EXPORT ScreenPtr DRI2DrawableGetScreen(DRI2DrawablePtr pPriv);
* \return Valid DRI2DrawablePtr if DRI2Drawable exists. Otherwise NULL.
*/
extern _X_EXPORT DRI2DrawablePtr DRI2GetDrawable(DrawablePtr pDraw);
+
+extern _X_EXPORT int DRI2LookupDrawableComplex(ClientPtr client,
+ XID id,
+ DRI2DrawablePtr *pPriv);
#endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index bac7b79ba..beadc832b 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -66,10 +66,8 @@ validDRI2Drawable(ClientPtr client, XID id, Mask access,
rc = dixLookupResourceByType((pointer*)&pTmp, id, dri2DrawableRes, client, access);
- if (rc == BadValue) {
- *status = BadDrawable;
- return FALSE;
- }
+ if (rc == BadValue)
+ rc = DRI2LookupDrawableComplex(client, id, &pTmp);
*status = rc;
if (rc != Success)
return FALSE;