diff options
Diffstat (limited to 'GL/glx/glxcmds.c')
-rw-r--r-- | GL/glx/glxcmds.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index 3ec796c0f..e2aaf3a71 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -1605,8 +1605,13 @@ int __glXReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) { xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLXContextTag tag = req->contextTag; + __GLXcontext *glxc = NULL; + __GLXdrawable *pGlxDraw; + __GLXpixmap *pPixmap; ClientPtr client = cl->client; GLXDrawable drawId; + int error; int x, y, width, height; (void) client; @@ -1620,7 +1625,40 @@ int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) width = *((INT32 *) (pc + 12)); height = *((INT32 *) (pc + 16)); - return BadRequest; + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) { + return __glXError(GLXBadContextTag); + } + /* + ** The calling thread is swapping its current drawable. In this case, + ** glxSwapBuffers is in both GL and X streams, in terms of + ** sequentiality. + */ + if (__glXForceCurrent(cl, tag, &error)) { + /* + ** Do whatever is needed to make sure that all preceding requests + ** in both streams are completed before the swap is executed. + */ + CALL_Finish( GET_DISPATCH(), () ); + __GLX_NOTE_FLUSHED_CMDS(glxc); + } else { + return error; + } + } + + error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client); + if (error != Success) + return error; + + if (pGlxDraw == NULL || + pGlxDraw->type != DRAWABLE_WINDOW || + pGlxDraw->copySubBuffer == NULL) + return __glXError(GLXBadDrawable); + + (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height); + + return Success; } /* |