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

Reply via email to