--- glx/glxdrawable.h.orig 2011-06-11 19:55:47.000000000 +0300 +++ glx/glxdrawable.h 2011-07-28 11:36:02.122815920 +0300 @@ -51,8 +51,11 @@ struct __GLXdrawable { void (*waitX)(__GLXdrawable *); void (*waitGL)(__GLXdrawable *); + int refcnt; /* number of resources handles referencing this */ + DrawablePtr pDraw; XID drawId; + XID otherId; /* for glx1.3 we need to track the original Drawable as well */ /* ** Either GLX_DRAWABLE_PIXMAP, GLX_DRAWABLE_WINDOW or --- glx/glxcmds.c.orig 2011-06-11 19:55:47.000000000 +0300 +++ glx/glxcmds.c 2011-07-28 12:08:40.412582475 +0300 @@ -496,6 +496,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLX *error = BadAlloc; return NULL; } + pGlxDraw->refcnt++; return pGlxDraw; } @@ -1095,8 +1096,10 @@ __glXDrawableInit(__GLXdrawable *drawabl drawable->pDraw = pDraw; drawable->type = type; drawable->drawId = drawId; + drawable->otherId = 0; drawable->config = config; drawable->eventMask = 0; + drawable->refcnt = 0; return GL_TRUE; } @@ -1126,15 +1129,20 @@ DoCreateGLXDrawable(ClientPtr client, __ pGlxDraw->destroy (pGlxDraw); return BadAlloc; } + pGlxDraw->refcnt++; /* * Windows aren't refcounted, so track both the X and the GLX window * so we get called regardless of destruction order. */ - if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW && - !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) { - pGlxDraw->destroy (pGlxDraw); - return BadAlloc; + if (drawableId != glxDrawableId && + (type == GLX_DRAWABLE_WINDOW || type == GLX_DRAWABLE_PIXMAP)) { + if (!AddResource(drawableId, __glXDrawableRes, pGlxDraw)) { + pGlxDraw->destroy (pGlxDraw); + return BadAlloc; + } + pGlxDraw->refcnt++; + pGlxDraw->otherId = drawableId; } return Success; --- glx/glxext.c.orig 2011-06-11 19:55:47.000000000 +0300 +++ glx/glxext.c 2011-07-28 12:10:25.742582240 +0300 @@ -124,14 +124,19 @@ static Bool DrawableGone(__GLXdrawable * { __GLXcontext *c, *next; - if (glxPriv->type == GLX_DRAWABLE_WINDOW) { + if (glxPriv->type == GLX_DRAWABLE_WINDOW || glxPriv->type == GLX_DRAWABLE_PIXMAP) { /* If this was created by glXCreateWindow, free the matching resource */ - if (glxPriv->drawId != glxPriv->pDraw->id) { - if (xid == glxPriv->drawId) - FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE); - else - FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE); - } + if (glxPriv->otherId) { + XID other = glxPriv->otherId; + glxPriv->otherId = 0; + if (xid == other) + FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE); + else + FreeResourceByType(other, __glXDrawableRes, TRUE); + } + + if (--glxPriv->refcnt) + return True; /* otherwise this window was implicitly created by MakeCurrent */ }