diff options
Diffstat (limited to 'xorg-server/glx/glxcmds.c')
-rw-r--r-- | xorg-server/glx/glxcmds.c | 281 |
1 files changed, 140 insertions, 141 deletions
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c index ff8b126be..f5632d162 100644 --- a/xorg-server/glx/glxcmds.c +++ b/xorg-server/glx/glxcmds.c @@ -28,8 +28,6 @@ * Silicon Graphics, Inc. */ -#define NEED_REPLIES -#define FONT_PCF #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif @@ -53,12 +51,6 @@ #include "indirect_table.h" #include "indirect_util.h" -void -GlxSetRenderTables (struct _glapi_table *table) -{ - _glapi_set_dispatch (table); -} - static int validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) { @@ -139,6 +131,58 @@ validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config, return TRUE; } +static int +validGlxContext(ClientPtr client, XID id, int access_mode, + __GLXcontext **context, int *err) +{ + *err = dixLookupResourceByType((pointer *) context, id, + __glXContextRes, client, access_mode); + if (*err != Success) { + client->errorValue = id; + if (*err == BadValue) + *err = __glXError(GLXBadContext); + return FALSE; + } + + return TRUE; +} + +static int +validGlxDrawable(ClientPtr client, XID id, int type, int access_mode, + __GLXdrawable **drawable, int *err) +{ + int rc; + + rc = dixLookupResourceByType((pointer *) drawable, id, + __glXDrawableRes, client, access_mode); + if (rc != Success && rc != BadValue) { + *err = rc; + client->errorValue = id; + return FALSE; + } + + if (rc == BadValue || + (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) { + client->errorValue = id; + switch (type) { + case GLX_DRAWABLE_WINDOW: + *err = __glXError(GLXBadWindow); + return FALSE; + case GLX_DRAWABLE_PIXMAP: + *err = __glXError(GLXBadPixmap); + return FALSE; + case GLX_DRAWABLE_PBUFFER: + *err = __glXError(GLXBadPbuffer); + return FALSE; + case GLX_DRAWABLE_ANY: + *err = __glXError(GLXBadDrawable); + return FALSE; + } + } + + return TRUE; +} + void __glXContextDestroy(__GLXcontext *context) { @@ -181,7 +225,8 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, { ClientPtr client = cl->client; __GLXcontext *glxc, *shareglxc; - + int err; + LEGAL_NEW_RESOURCE(gcId, client); /* @@ -196,11 +241,10 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, if (shareList == None) { shareglxc = 0; } else { - shareglxc = (__GLXcontext *) LookupIDByType(shareList, __glXContextRes); - if (!shareglxc) { - client->errorValue = shareList; - return __glXError(GLXBadContext); - } + if (!validGlxContext(client, shareList, DixReadAccess, + &shareglxc, &err)) + return err; + if (shareglxc->isDirect) { /* ** NOTE: no support for sharing display lists between direct @@ -315,25 +359,16 @@ int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) } int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) { - ClientPtr client = cl->client; xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; - GLXContextID gcId = req->context; __GLXcontext *glxc; - - glxc = (__GLXcontext *) LookupIDByType(gcId, __glXContextRes); - if (glxc) { - /* - ** Just free the resource; don't actually destroy the context, - ** because it might be in use. The - ** destroy method will be called by the resource destruction routine - ** if necessary. - */ - FreeResourceByType(gcId, __glXContextRes, FALSE); - return Success; - } else { - client->errorValue = gcId; - return __glXError(GLXBadContext); - } + int err; + + if (!validGlxContext(cl->client, req->context, DixDestroyAccess, + &glxc, &err)) + return err; + + FreeResourceByType(req->context, __glXContextRes, FALSE); + return Success; } /*****************************************************************************/ @@ -428,20 +463,10 @@ static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) } /** - * Given a drawable ID, get the associated drawable and / or pixmap. - * - * If the specified drawable ID is not a pixmap, \c ppPixmap will be set - * to \c NULL on return. In either case, \c ppDraw will be set to a drawable. - * In the case where the drawable ID is a pixmap, \c ppDraw will be set to - * the drawable associated with that pixmap. - * - * \param glxc Associated GLX context. - * \param drawId ID of the drawable. - * \param client Pointer to the client state. - * \return the __GLXdrawable is returned on success. Otherwise NULL. - * - * \notes This function will need some modification when support pbuffers - * is added. + * This is a helper function to handle the legacy (pre GLX 1.3) cases + * where passing an X window to glXMakeCurrent is valid. Given a + * resource ID, look up the GLX drawable if available, otherwise, make + * sure it's an X window and create a GLX drawable one the fly. */ static __GLXdrawable * __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, @@ -451,10 +476,8 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, __GLXdrawable *pGlxDraw; int rc; - /* This is the GLX 1.3 case - the client passes in a GLXWindow or - * GLXPixmap and we just return the __GLXdrawable. */ - pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes); - if (pGlxDraw != NULL) { + if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, + DixWriteAccess, &pGlxDraw, &rc)) { if (glxc != NULL && pGlxDraw->config != glxc->config) { client->errorValue = drawId; *error = BadMatch; @@ -464,13 +487,10 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, return pGlxDraw; } - /* The drawId wasn't a GLX drawable, so presumably it's a regular - * X window. In that case, we create a shadow GLXWindow for it on - * demand here for pre GLX 1.3 compatibility and use the X Window - * XID as its GLXWindow XID. The client can't explicitly create a - * GLXWindow with the same XID as an X Window, so we wont get any - * resource ID clashes. Effectively, the X Window is now also a - * GLXWindow. */ + /* The drawId wasn't a GLX drawable. Make sure it's a window and + * create a GLXWindow for it. Check that the drawable screen + * matches the context screen and that the context fbconfig is + * compatible with the window visual. */ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); if (rc != Success || pDraw->type != DRAWABLE_WINDOW) { @@ -479,18 +499,13 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, return NULL; } - /* If we're not given a context, don't create the __GLXdrawable */ - if (glxc == NULL) { - *error = __glXError(GLXBadDrawable); + if (pDraw->pScreen != glxc->pGlxScreen->pScreen) { + client->errorValue = pDraw->pScreen->myNum; + *error = BadMatch; return NULL; } - /* We're binding an X Window for the first time and need to create - * a GLX drawable for it. Check that the drawable screen matches - * the context screen and that the context fbconfig is compatible - * with the window visual. */ - if (pDraw->pScreen != glxc->pGlxScreen->pScreen || - !validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) + if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) return NULL; pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, @@ -522,7 +537,7 @@ DoMakeCurrent(__GLXclientState *cl, __GLXcontext *glxc, *prevglxc; __GLXdrawable *drawPriv = NULL; __GLXdrawable *readPriv = NULL; - GLint error; + int error; GLuint mask; /* @@ -563,11 +578,8 @@ DoMakeCurrent(__GLXclientState *cl, if (contextId != None) { int status; - glxc = (__GLXcontext *) LookupIDByType(contextId, __glXContextRes); - if (!glxc) { - client->errorValue = contextId; - return __glXError(GLXBadContext); - } + if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error)) + return error; if ((glxc != prevglxc) && glxc->isCurrent) { /* Context is current to somebody else */ return BadAccess; @@ -690,15 +702,10 @@ int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc) xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; xGLXIsDirectReply reply; __GLXcontext *glxc; + int err; - /* - ** Find the GL context. - */ - glxc = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes); - if (!glxc) { - client->errorValue = req->context; - return __glXError(GLXBadContext); - } + if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err)) + return err; reply.isDirect = glxc->isDirect; reply.length = 0; @@ -785,8 +792,8 @@ int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc) return error; } - if (glxc && glxc->drawPriv->waitGL) - (*glxc->drawPriv->waitGL)(glxc->drawPriv); + if (glxc && glxc->drawPriv->waitX) + (*glxc->drawPriv->waitX)(glxc->drawPriv); return Success; } @@ -802,19 +809,10 @@ int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc) __GLXcontext *src, *dst; int error; - /* - ** Check that each context exists. - */ - src = (__GLXcontext *) LookupIDByType(source, __glXContextRes); - if (!src) { - client->errorValue = source; - return __glXError(GLXBadContext); - } - dst = (__GLXcontext *) LookupIDByType(dest, __glXContextRes); - if (!dst) { - client->errorValue = dest; - return __glXError(GLXBadContext); - } + if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error)) + return error; + if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error)) + return error; /* ** They must be in the same address space, and same screen. @@ -872,6 +870,14 @@ int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc) return Success; } +enum { + GLX_VIS_CONFIG_UNPAIRED = 18, + GLX_VIS_CONFIG_PAIRED = 20 +}; + +enum { + GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED +}; int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) { @@ -880,7 +886,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) xGLXGetVisualConfigsReply reply; __GLXscreen *pGlxScreen; __GLXconfig *modes; - CARD32 buf[__GLX_TOTAL_CONFIG]; + CARD32 buf[GLX_VIS_CONFIG_TOTAL]; int p, i, err; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; @@ -889,8 +895,8 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) return err; reply.numVisuals = pGlxScreen->numVisuals; - reply.numProps = __GLX_TOTAL_CONFIG; - reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG) >> 2; + reply.numProps = GLX_VIS_CONFIG_TOTAL; + reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2; reply.type = X_Reply; reply.sequenceNumber = client->sequence; @@ -928,6 +934,8 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) buf[p++] = modes->stencilBits; buf[p++] = modes->numAuxBuffers; buf[p++] = modes->level; + + assert(p == GLX_VIS_CONFIG_UNPAIRED); /* ** Add token/value pairs for extensions. */ @@ -952,11 +960,11 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */ buf[p++] = 0; + assert(p == GLX_VIS_CONFIG_TOTAL); if (client->swapped) { - __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG); + __GLX_SWAP_INT_ARRAY(buf, p); } - WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, - (char *)buf); + WriteToClient(client, __GLX_SIZE_CARD32 * p, (char *)buf); } return Success; } @@ -1131,7 +1139,11 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config int err; err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess); - if (err != Success || pDraw->type != DRAWABLE_PIXMAP) { + if (err != Success) { + client->errorValue = drawableId; + return err; + } + if (pDraw->type != DRAWABLE_PIXMAP) { client->errorValue = drawableId; return BadPixmap; } @@ -1146,14 +1158,18 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config } static void -determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs) +determineTextureTarget(ClientPtr client, XID glxDrawableID, + CARD32 *attribs, CARD32 numAttribs) { GLenum target = 0; GLenum format = 0; - int i; + int i, err; __GLXdrawable *pGlxDraw; - pGlxDraw = LookupIDByType(glxDrawableID, __glXDrawableRes); + if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP, + DixWriteAccess, &pGlxDraw, &err)) + /* We just added it in CreatePixmap, so we should never get here. */ + return; for (i = 0; i < numAttribs; i++) { if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { @@ -1217,7 +1233,7 @@ int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) if (err != Success) return err; - determineTextureTarget(req->glxpixmap, + determineTextureTarget(cl->client, req->glxpixmap, (CARD32*) (req + 1), req->numAttribs); return Success; @@ -1243,24 +1259,12 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type) { - ClientPtr client = cl->client; __GLXdrawable *pGlxDraw; + int err; - /* - ** Check it's the right type of drawable. - */ - pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes); - if (pGlxDraw == NULL || pGlxDraw->type != type) { - client->errorValue = glxdrawable; - switch (type) { - case GLX_DRAWABLE_WINDOW: - return __glXError(GLXBadWindow); - case GLX_DRAWABLE_PIXMAP: - return __glXError(GLXBadDrawable); - case GLX_DRAWABLE_PBUFFER: - return __glXError(GLXBadPbuffer); - } - } + if (!validGlxDrawable(cl->client, glxdrawable, type, + DixDestroyAccess, &pGlxDraw, &err)) + return err; FreeResource(glxdrawable, FALSE); @@ -1360,9 +1364,12 @@ DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable, int numAttribs, CARD32 *attribs) { __GLXdrawable *pGlxDraw; - int i; + int i, err; + + if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY, + DixSetAttrAccess, &pGlxDraw, &err)) + return err; - pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes); for (i = 0; i < numAttribs; i++) { switch(attribs[i * 2]) { case GLX_EVENT_MASK: @@ -1490,12 +1497,10 @@ DoQueryContext(__GLXclientState *cl, GLXContextID gcId) int nProps; int *sendBuf, *pSendBuf; int nReplyBytes; + int err; - ctx = (__GLXcontext *) LookupIDByType(gcId, __glXContextRes); - if (!ctx) { - client->errorValue = gcId; - return __glXError(GLXBadContext); - } + if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err)) + return err; nProps = 3; reply.length = nProps << 1; @@ -1563,11 +1568,9 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc) if (!context) return error; - pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error); - if (!pGlxDraw || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) { - client->errorValue = drawId; - return __glXError(GLXBadPixmap); - } + if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, + DixReadAccess, &pGlxDraw, &error)) + return error; if (!context->textureFromPixmap) return __glXError(GLXUnsupportedPrivateRequest); @@ -1596,11 +1599,9 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) if (!context) return error; - pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error); - if (!pGlxDraw || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) { - client->errorValue = drawId; + if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, + DixReadAccess, &pGlxDraw, &error)) return error; - } if (!context->textureFromPixmap) return __glXError(GLXUnsupportedPrivateRequest); @@ -1680,11 +1681,9 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId) CARD32 attributes[6]; int numAttribs, error; - pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error); - if (!pGlxDraw) { - client->errorValue = drawId; + if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, + DixGetAttrAccess, &pGlxDraw, &error)) return error; - } numAttribs = 3; reply.length = numAttribs << 1; |