The spec says (regarding glXCreateWindow): "If there is already a GLXFBConfig associated with win (as a result of a previous glXCreateWindow call), then a BadAlloc error is generated.". It will also come useful to implement DRI2InvalidateBuffers for the indirect case.
Signed-off-by: Francisco Jerez <curroje...@riseup.net> --- glx/glxcmds.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------ glx/glxserver.h | 1 + 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/glx/glxcmds.c b/glx/glxcmds.c index 77afbf4..0e1c89c 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -51,6 +51,15 @@ #include "indirect_table.h" #include "indirect_util.h" +static int glxWindowPrivateKeyIndex; +static DevPrivateKey glxWindowPrivateKey = &glxWindowPrivateKeyIndex; + +__GLXdrawable * +glxGetDrawableFromWindow(WindowPtr pWin) +{ + return dixLookupPrivate(&pWin->devPrivates, glxWindowPrivateKey); +} + static int validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) { @@ -473,6 +482,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, int *error) { DrawablePtr pDraw; + WindowPtr pWin; __GLXdrawable *pGlxDraw; int rc; @@ -499,6 +509,12 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, return NULL; } + pWin = (WindowPtr)pDraw; + + pGlxDraw = glxGetDrawableFromWindow(pWin); + if (pGlxDraw) + return pGlxDraw; + if (pDraw->pScreen != glxc->pGlxScreen->pScreen) { client->errorValue = pDraw->pScreen->myNum; *error = BadMatch; @@ -519,6 +535,8 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, return NULL; } + dixSetPrivate(&pWin->devPrivates, glxWindowPrivateKey, pGlxDraw); + return pGlxDraw; } @@ -1107,9 +1125,10 @@ __glXDrawableRelease(__GLXdrawable *drawable) } } -static int +static int DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, - DrawablePtr pDraw, XID glxDrawableId, int type) + DrawablePtr pDraw, XID glxDrawableId, int type, + __GLXdrawable **ret) { __GLXdrawable *pGlxDraw; @@ -1128,6 +1147,9 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf return BadAlloc; } + if (ret) + *ret = pGlxDraw; + return Success; } @@ -1149,7 +1171,7 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config } err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, - glxDrawableId, GLX_DRAWABLE_PIXMAP); + glxDrawableId, GLX_DRAWABLE_PIXMAP, NULL); if (err == Success) ((PixmapPtr) pDraw)->refcnt++; @@ -1305,7 +1327,7 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, __glXleaveServer(GL_FALSE); return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, - glxDrawableId, GLX_DRAWABLE_PBUFFER); + glxDrawableId, GLX_DRAWABLE_PBUFFER, NULL); } int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) @@ -1409,6 +1431,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) __GLXscreen *pGlxScreen; ClientPtr client = cl->client; DrawablePtr pDraw; + WindowPtr pWin; + __GLXdrawable *pGlxDraw; int err; if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) @@ -1422,11 +1446,26 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) return BadWindow; } + pWin = (WindowPtr)pDraw; + + /* Make sure there're no already associated GLX drawables. */ + if (glxGetDrawableFromWindow(pWin)) { + client->errorValue = req->window; + return BadAlloc; + } + if (!validGlxFBConfigForWindow(client, config, pDraw, &err)) return err; - return DoCreateGLXDrawable(client, pGlxScreen, config, - pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW); + err = DoCreateGLXDrawable(client, pGlxScreen, config, + pDraw, req->glxwindow, + GLX_DRAWABLE_WINDOW, &pGlxDraw); + if (err) + return err; + + dixSetPrivate(&pWin->devPrivates, glxWindowPrivateKey, pGlxDraw); + + return Success; } int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc) diff --git a/glx/glxserver.h b/glx/glxserver.h index 1daf977..3c49b5e 100644 --- a/glx/glxserver.h +++ b/glx/glxserver.h @@ -80,6 +80,7 @@ typedef struct __GLXcontext __GLXcontext; extern __GLXscreen *glxGetScreen(ScreenPtr pScreen); extern __GLXclientState *glxGetClient(ClientPtr pClient); +extern __GLXdrawable *glxGetDrawableFromWindow(WindowPtr pWin); /************************************************************************/ -- 1.6.4.4 ------------------------------------------------------------------------------ Throughout its 18-year history, RSA Conference consistently attracts the world's best and brightest in the field, creating opportunities for Conference attendees to learn about information security's most important issues through interactions with peers, luminaries and emerging and established companies. http://p.sf.net/sfu/rsaconf-dev2dev _______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mesa3d-dev