summaryrefslogtreecommitdiff
path: root/GL/glx/glxcmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'GL/glx/glxcmds.c')
-rw-r--r--GL/glx/glxcmds.c40
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;
}
/*