Move __GLXdrawable lookup and creation into GetDrawableOrPixmap.
Also refactors __glXSwapBuffers to use GetDrawableOrPixmap for getting the __GLXdrawable. This patch paves the way for GLXWindows with XIDs different from the X Windows they are created for, a prerequisite for glXCreateWindow().
This commit is contained in:
parent
8b5bc6a9ab
commit
ee012588d2
176
GL/glx/glxcmds.c
176
GL/glx/glxcmds.c
|
@ -445,29 +445,46 @@ int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
|
||||||
* is added.
|
* is added.
|
||||||
*/
|
*/
|
||||||
static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId,
|
static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId,
|
||||||
DrawablePtr *ppDraw, __GLXpixmap **ppPixmap,
|
__GLXdrawable **ppGlxDraw,
|
||||||
|
__GLXpixmap **ppPixmap,
|
||||||
ClientPtr client )
|
ClientPtr client )
|
||||||
{
|
{
|
||||||
DrawablePtr pDraw;
|
DrawablePtr pDraw;
|
||||||
|
__GLcontextModes *modes;
|
||||||
|
__GLXdrawable *pGlxDraw;
|
||||||
__GLXpixmap *drawPixmap = NULL;
|
__GLXpixmap *drawPixmap = NULL;
|
||||||
|
|
||||||
|
/* This is the GLX 1.3 case - the client passes in a GLXWindow and
|
||||||
|
* we just return the __GLXdrawable. The first time a GLXPixmap
|
||||||
|
* comes in, it doesn't have a corresponding __GLXdrawable, so it
|
||||||
|
* falls through to the else-case below, but after that it'll have
|
||||||
|
* a __GLXdrawable and we'll handle it here. */
|
||||||
|
pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes);
|
||||||
|
if (pGlxDraw != NULL) {
|
||||||
|
if (glxc != NULL && pGlxDraw->modes != glxc->modes) {
|
||||||
|
client->errorValue = drawId;
|
||||||
|
return BadMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppGlxDraw = pGlxDraw;
|
||||||
|
*ppPixmap = pGlxDraw->pGlxPixmap;
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The drawId wasn't a GLXWindow, 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. */
|
||||||
pDraw = (DrawablePtr) LookupDrawable(drawId, client);
|
pDraw = (DrawablePtr) LookupDrawable(drawId, client);
|
||||||
if (pDraw) {
|
if (pDraw) {
|
||||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
if (pDraw->type == DRAWABLE_WINDOW) {
|
||||||
/*
|
VisualID vid = wVisual((WindowPtr)pDraw);
|
||||||
** Drawable is an X Window.
|
|
||||||
*/
|
|
||||||
WindowPtr pWin = (WindowPtr)pDraw;
|
|
||||||
VisualID vid = wVisual(pWin);
|
|
||||||
|
|
||||||
/*
|
modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes,
|
||||||
** Check if window and context are similar.
|
vid);
|
||||||
*/
|
|
||||||
if ((vid != glxc->pVisual->vid) ||
|
|
||||||
(pWin->drawable.pScreen != glxc->pScreen)) {
|
|
||||||
client->errorValue = drawId;
|
|
||||||
return BadMatch;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
** An X Pixmap is not allowed as a parameter (a GLX Pixmap
|
** An X Pixmap is not allowed as a parameter (a GLX Pixmap
|
||||||
|
@ -479,16 +496,8 @@ static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId,
|
||||||
} else {
|
} else {
|
||||||
drawPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes);
|
drawPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes);
|
||||||
if (drawPixmap) {
|
if (drawPixmap) {
|
||||||
/*
|
|
||||||
** Check if pixmap and context are similar.
|
|
||||||
*/
|
|
||||||
if (drawPixmap->pScreen != glxc->pScreen ||
|
|
||||||
drawPixmap->modes->visualID != glxc->modes->visualID) {
|
|
||||||
client->errorValue = drawId;
|
|
||||||
return BadMatch;
|
|
||||||
}
|
|
||||||
pDraw = drawPixmap->pDraw;
|
pDraw = drawPixmap->pDraw;
|
||||||
|
modes = drawPixmap->modes;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
** Drawable is neither a Window nor a GLXPixmap.
|
** Drawable is neither a Window nor a GLXPixmap.
|
||||||
|
@ -498,8 +507,33 @@ static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we're not given a context, don't create the __GLXdrawable */
|
||||||
|
if (glxc == NULL) {
|
||||||
|
*ppPixmap = NULL;
|
||||||
|
*ppGlxDraw = NULL;
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're binding an X Window or a GLX Pixmap for the first time
|
||||||
|
* and need to create a GLX drawable for it. First check that the
|
||||||
|
* drawable screen and fbconfig matches the context ditto. */
|
||||||
|
if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) {
|
||||||
|
client->errorValue = drawId;
|
||||||
|
return BadMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
pGlxDraw =
|
||||||
|
glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
|
||||||
|
pDraw, drawId, modes);
|
||||||
|
|
||||||
|
/* since we are creating the drawablePrivate, drawId should be new */
|
||||||
|
if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
|
||||||
|
pGlxDraw->destroy (pGlxDraw);
|
||||||
|
return BadAlloc;
|
||||||
|
}
|
||||||
|
|
||||||
*ppPixmap = drawPixmap;
|
*ppPixmap = drawPixmap;
|
||||||
*ppDraw = pDraw;
|
*ppGlxDraw = pGlxDraw;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -510,8 +544,6 @@ int DoMakeCurrent( __GLXclientState *cl,
|
||||||
GLXContextID contextId, GLXContextTag tag )
|
GLXContextID contextId, GLXContextTag tag )
|
||||||
{
|
{
|
||||||
ClientPtr client = cl->client;
|
ClientPtr client = cl->client;
|
||||||
DrawablePtr pDraw;
|
|
||||||
DrawablePtr pRead;
|
|
||||||
xGLXMakeCurrentReply reply;
|
xGLXMakeCurrentReply reply;
|
||||||
__GLXpixmap *drawPixmap = NULL;
|
__GLXpixmap *drawPixmap = NULL;
|
||||||
__GLXpixmap *readPixmap = NULL;
|
__GLXpixmap *readPixmap = NULL;
|
||||||
|
@ -572,36 +604,18 @@ int DoMakeCurrent( __GLXclientState *cl,
|
||||||
assert( drawId != None );
|
assert( drawId != None );
|
||||||
assert( readId != None );
|
assert( readId != None );
|
||||||
|
|
||||||
status = GetDrawableOrPixmap( glxc, drawId, & pDraw, & drawPixmap,
|
status = GetDrawableOrPixmap(glxc, drawId, &drawPriv, &drawPixmap,
|
||||||
client );
|
client);
|
||||||
if ( status != 0 ) {
|
if ( status != 0 ) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( readId != drawId ) {
|
if ( readId != drawId ) {
|
||||||
status = GetDrawableOrPixmap( glxc, readId, & pRead, & readPixmap,
|
status = GetDrawableOrPixmap(glxc, readId, &readPriv, &readPixmap,
|
||||||
client );
|
client);
|
||||||
if ( status != 0 ) {
|
if ( status != 0 ) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
pRead = pDraw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Finish refactoring this. - idr */
|
|
||||||
/* get the drawable private */
|
|
||||||
if (pDraw) {
|
|
||||||
drawPriv = __glXGetDrawable(glxc, pDraw, drawId);
|
|
||||||
if (drawPriv == NULL) {
|
|
||||||
return __glXError(GLXBadDrawable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pRead != pDraw) {
|
|
||||||
readPriv = __glXGetDrawable(glxc, pRead, readId);
|
|
||||||
if (readPriv == NULL) {
|
|
||||||
return __glXError(GLXBadDrawable);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
readPriv = drawPriv;
|
readPriv = drawPriv;
|
||||||
}
|
}
|
||||||
|
@ -609,8 +623,8 @@ int DoMakeCurrent( __GLXclientState *cl,
|
||||||
} else {
|
} else {
|
||||||
/* Switching to no context. Ignore new drawable. */
|
/* Switching to no context. Ignore new drawable. */
|
||||||
glxc = 0;
|
glxc = 0;
|
||||||
pDraw = 0;
|
drawPriv = 0;
|
||||||
pRead = 0;
|
readPriv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1386,45 +1400,13 @@ int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc)
|
||||||
int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
|
int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
|
||||||
{
|
{
|
||||||
ClientPtr client = cl->client;
|
ClientPtr client = cl->client;
|
||||||
DrawablePtr pDraw;
|
|
||||||
xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
|
xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
|
||||||
GLXContextTag tag = req->contextTag;
|
GLXContextTag tag = req->contextTag;
|
||||||
XID drawId = req->drawable;
|
XID drawId = req->drawable;
|
||||||
__GLXpixmap *pGlxPixmap;
|
|
||||||
__GLXcontext *glxc = NULL;
|
__GLXcontext *glxc = NULL;
|
||||||
|
__GLXdrawable *pGlxDraw;
|
||||||
|
__GLXpixmap *pPixmap;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/*
|
|
||||||
** Check that the GLX drawable is valid.
|
|
||||||
*/
|
|
||||||
pDraw = (DrawablePtr) LookupDrawable(drawId, client);
|
|
||||||
if (pDraw) {
|
|
||||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
|
||||||
/*
|
|
||||||
** Drawable is an X window.
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
** Drawable is an X pixmap, which is not allowed.
|
|
||||||
*/
|
|
||||||
client->errorValue = drawId;
|
|
||||||
return __glXError(GLXBadDrawable);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
|
|
||||||
__glXPixmapRes);
|
|
||||||
if (pGlxPixmap) {
|
|
||||||
/*
|
|
||||||
** Drawable is a GLX pixmap.
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
** Drawable is neither a X window nor a GLX pixmap.
|
|
||||||
*/
|
|
||||||
client->errorValue = drawId;
|
|
||||||
return __glXError(GLXBadDrawable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag) {
|
if (tag) {
|
||||||
glxc = __glXLookupContextByTag(cl, tag);
|
glxc = __glXLookupContextByTag(cl, tag);
|
||||||
|
@ -1448,27 +1430,13 @@ int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDraw) {
|
error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client);
|
||||||
__GLXdrawable *glxPriv;
|
if (error != Success)
|
||||||
|
return error;
|
||||||
|
|
||||||
if (glxc) {
|
if (pGlxDraw != NULL && pGlxDraw->type == DRAWABLE_WINDOW &&
|
||||||
glxPriv = __glXGetDrawable(glxc, pDraw, drawId);
|
(*pGlxDraw->swapBuffers)(pGlxDraw) == GL_FALSE)
|
||||||
if (glxPriv == NULL) {
|
return __glXError(GLXBadDrawable);
|
||||||
return __glXError(GLXBadDrawable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
glxPriv = __glXFindDrawable(drawId);
|
|
||||||
if (glxPriv == NULL) {
|
|
||||||
/* This is a window we've never seen before, do nothing */
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*glxPriv->swapBuffers)(glxPriv) == GL_FALSE) {
|
|
||||||
return __glXError(GLXBadDrawable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,53 +155,3 @@ __glXDrawableInit(__GLXdrawable *drawable,
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
__GLXdrawable *
|
|
||||||
__glXFindDrawable(XID drawId)
|
|
||||||
{
|
|
||||||
__GLXdrawable *glxPriv;
|
|
||||||
|
|
||||||
glxPriv = (__GLXdrawable *)LookupIDByType(drawId, __glXDrawableRes);
|
|
||||||
|
|
||||||
return glxPriv;
|
|
||||||
}
|
|
||||||
|
|
||||||
__GLXdrawable *
|
|
||||||
__glXGetDrawable(__GLXcontext *ctx, DrawablePtr pDraw, XID drawId)
|
|
||||||
{
|
|
||||||
__GLXscreen *pGlxScreen = ctx->pGlxScreen;
|
|
||||||
__GLXdrawable *glxPriv;
|
|
||||||
__GLcontextModes *modes;
|
|
||||||
|
|
||||||
glxPriv = __glXFindDrawable(drawId);
|
|
||||||
|
|
||||||
if (glxPriv == NULL)
|
|
||||||
{
|
|
||||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
|
||||||
VisualID vid = wVisual((WindowPtr)pDraw);
|
|
||||||
|
|
||||||
modes = _gl_context_modes_find_visual(pGlxScreen->modes, vid);
|
|
||||||
} else {
|
|
||||||
__GLXpixmap *pGlxPixmap =
|
|
||||||
(__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes);
|
|
||||||
|
|
||||||
/* We never get here without a valid pixmap.
|
|
||||||
* GetDrawableOrPixmap weeds out X Pixmaps without GLX
|
|
||||||
* pixmaps for us. */
|
|
||||||
|
|
||||||
modes = pGlxPixmap->modes;
|
|
||||||
}
|
|
||||||
|
|
||||||
glxPriv =
|
|
||||||
pGlxScreen->createDrawable(ctx->pGlxScreen, pDraw, drawId, modes);
|
|
||||||
|
|
||||||
/* since we are creating the drawablePrivate, drawId should be new */
|
|
||||||
if (!AddResource(drawId, __glXDrawableRes, glxPriv))
|
|
||||||
{
|
|
||||||
glxPriv->destroy (glxPriv);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return glxPriv;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue