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 _______________________________________________ xorg-devel mailing list xorg-devel@lists.x.org http://lists.x.org/mailman/listinfo/xorg-devel