/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DMX_CONFIG_H #include #endif #include "dmx.h" #include "dmxwindow.h" #include "dmxpixmap.h" #include "dmxfont.h" #include "dmxsync.h" #undef Xmalloc #undef Xcalloc #undef Xrealloc #undef Xfree #include "glxserver.h" #include #include "g_disptab.h" #include #include #include "glxutil.h" #include "glxext.h" #include "unpack.h" #include "GL/glxproto.h" #include "glxvendor.h" #include "glxvisuals.h" #include "glxswap.h" #ifdef PANORAMIX #include "panoramiXsrv.h" #endif extern __GLXFBConfig **__glXFBConfigs; extern int __glXNumFBConfigs; extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id ); extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid ); extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen ); extern int glxIsExtensionSupported( char *ext ); extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc); #define BE_TO_CLIENT_ERROR(x) \ ( (x) >= __glXerrorBase ? \ (x) - dmxScreen->glxErrorBase + __glXerrorBase \ : (x) ) Display *GetBackEndDisplay( __GLXclientState *cl, int s ) { if (! cl->be_displays[s] ) { cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) ); } return( cl->be_displays[s] ); } /* ** Create a GL context with the given properties. */ static int CreateContext(__GLXclientState *cl, GLXContextID gcId, VisualID vid, GLXFBConfigID fbconfigId, int screen, GLXContextID shareList, int isDirect ) { ClientPtr client = cl->client; xGLXCreateContextReq *be_req; xGLXCreateNewContextReq *be_new_req; VisualPtr pVisual; ScreenPtr pScreen; __GLXcontext *glxc, *shareglxc; __GLXvisualConfig *pGlxVisual; __GLXscreenInfo *pGlxScreen; VisualID visual = vid; GLint i; int from_screen = screen; int to_screen = screen; DMXScreenInfo *dmxScreen; VisualID be_vid; GLXFBConfigID be_fbconfigId; int num_be_screens; Display *dpy; /* ** Check if screen exists. */ if (screen >= screenInfo.numScreens) { client->errorValue = screen; return BadValue; } #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif /* ** Find the display list space that we want to share. ** */ if (shareList == None) { shareglxc = NULL; } else { shareglxc = (__GLXcontext *) LookupIDByType(shareList, __glXContextRes); if (!shareglxc) { client->errorValue = shareList; return __glXBadContext; } } /* ** Allocate memory for the new context */ glxc = __glXCalloc(1, sizeof(__GLXcontext)); if (!glxc) { return BadAlloc; } pScreen = screenInfo.screens[screen]; pGlxScreen = &__glXActiveScreens[screen]; if (fbconfigId != None) { glxc->pFBConfig = glxLookupFBConfig( fbconfigId ); if (!glxc->pFBConfig) { client->errorValue = fbconfigId; __glXFree( glxc ); return BadValue; } visual = glxc->pFBConfig->associatedVisualId; } else { glxc->pFBConfig = NULL; } if (visual != None) { /* ** Check if the visual ID is valid for this screen. */ pVisual = pScreen->visuals; for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { if (pVisual->vid == visual) { break; } } if (i == pScreen->numVisuals) { client->errorValue = visual; __glXFree( glxc ); return BadValue; } pGlxVisual = pGlxScreen->pGlxVisual; for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { if (pGlxVisual->vid == visual) { break; } } if (i == pGlxScreen->numVisuals) { /* ** Visual not support on this screen by this OpenGL implementation. */ client->errorValue = visual; __glXFree( glxc ); return BadValue; } if ( glxc->pFBConfig == NULL ) { glxc->pFBConfig = glxLookupFBConfigByVID( visual ); if ( glxc->pFBConfig == NULL ) { /* * visual does not have an FBConfig ??? client->errorValue = visual; __glXFree( glxc ); return BadValue; */ } } } else { pVisual = NULL; pGlxVisual = NULL; } glxc->pScreen = pScreen; glxc->pGlxScreen = pGlxScreen; glxc->pVisual = pVisual; glxc->pGlxVisual = pGlxVisual; /* * allocate memory for back-end servers info */ num_be_screens = to_screen - from_screen + 1; glxc->real_ids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens); if (!glxc->real_ids) { return BadAlloc; } glxc->real_vids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens); if (!glxc->real_vids) { return BadAlloc; } for (screen = from_screen; screen <= to_screen; screen++) { int sent = 0; pScreen = screenInfo.screens[screen]; pGlxScreen = &__glXActiveScreens[screen]; dmxScreen = &dmxScreens[screen]; if (glxc->pFBConfig) { __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id, screen ); be_fbconfigId = beFBConfig->id; } if (pGlxVisual) { be_vid = glxMatchGLXVisualInConfigList( pGlxVisual, dmxScreen->glxVisuals, dmxScreen->numGlxVisuals ); if (!be_vid) { /* visual is not supported on the back-end server */ __glXFree( glxc->real_ids ); __glXFree( glxc->real_vids ); __glXFree( glxc ); return BadValue; } } glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen)); /* send the create context request to the back-end server */ dpy = GetBackEndDisplay(cl,screen); if (glxc->pFBConfig) { /*Since for a certain visual both RGB and COLOR INDEX *can be on then the only parmeter to choose the renderType * should be the class of the colormap since all 4 first * classes does not support RGB mode only COLOR INDEX , * and so TrueColor and DirectColor does not support COLOR INDEX*/ int renderType = glxc->pFBConfig->renderType; if ( pVisual ) { switch ( pVisual->class ){ case PseudoColor: case StaticColor: case GrayScale: case StaticGray: renderType = GLX_COLOR_INDEX_TYPE; break; case TrueColor: case DirectColor: default: renderType = GLX_RGBA_TYPE; break; } } if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { LockDisplay(dpy); GetReq(GLXCreateNewContext,be_new_req); be_new_req->reqType = dmxScreen->glxMajorOpcode; be_new_req->glxCode = X_GLXCreateNewContext; be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; be_new_req->fbconfig = (unsigned int)be_fbconfigId; be_new_req->screen = DefaultScreen(dpy); be_new_req->renderType = renderType; be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); be_new_req->isDirect = 0; UnlockDisplay(dpy); glxc->real_vids[screen-from_screen] = be_fbconfigId; sent = 1; } else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) { xGLXCreateContextWithConfigSGIXReq *ext_req; xGLXVendorPrivateReq *vpreq; LockDisplay(dpy); GetReqExtra(GLXVendorPrivate, sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq, vpreq); ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq; ext_req->reqType = dmxScreen->glxMajorOpcode; ext_req->glxCode = X_GLXVendorPrivate; ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX; ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; ext_req->fbconfig = (unsigned int)be_fbconfigId; ext_req->screen = DefaultScreen(dpy); ext_req->renderType = renderType; ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); ext_req->isDirect = 0; UnlockDisplay(dpy); glxc->real_vids[screen-from_screen] = be_fbconfigId; sent = 1; } } if (!sent) { LockDisplay(dpy); GetReq(GLXCreateContext,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXCreateContext; be_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; be_req->visual = (unsigned int)be_vid; be_req->screen = DefaultScreen(dpy); be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); be_req->isDirect = 0; UnlockDisplay(dpy); glxc->real_vids[screen-from_screen] = be_vid; } SyncHandle(); } /* ** Register this context as a resource. */ if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) { __glXFree( glxc->real_ids ); __glXFree( glxc->real_vids ); __glXFree( glxc ); client->errorValue = gcId; return BadAlloc; } /* ** Finally, now that everything is working, setup the rest of the ** context. */ glxc->id = gcId; glxc->share_id = shareList; glxc->idExists = GL_TRUE; glxc->isCurrent = GL_FALSE; return Success; } int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; return( CreateContext(cl, req->context,req->visual, None, req->screen, req->shareList, req->isDirect) ); } int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; return( CreateContext(cl, req->context,None, req->fbconfig, req->screen, req->shareList, req->isDirect) ); } int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; return( CreateContext(cl, req->context, None, req->fbconfig, req->screen, req->shareList, req->isDirect) ); } int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXQueryMaxSwapBarriersSGIXReq *req = (xGLXQueryMaxSwapBarriersSGIXReq *)pc; xGLXQueryMaxSwapBarriersSGIXReply reply; reply.type = X_Reply; reply.sequenceNumber = client->sequence; reply.length = 0; reply.max = QueryMaxSwapBarriersSGIX(req->screen); if (client->swapped) { __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply); } else { WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, (char *)&reply); } return Success; } int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc; DrawablePtr pDraw; __GLXpixmap *pGlxPixmap = NULL; __glXWindow *pGlxWindow = NULL; int rc; rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess); if (rc != Success) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable, __glXPixmapRes); if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable, __glXWindowRes); if (pGlxWindow) pDraw = pGlxWindow->pDraw; } if (!pDraw) { client->errorValue = req->drawable; return __glXBadDrawable; } return BindSwapBarrierSGIX(pDraw, req->barrier); } int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc; DrawablePtr pDraw, pMember = NULL; __GLXpixmap *pGlxPixmap = NULL; __glXWindow *pGlxWindow = NULL; int rc; rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess); if (rc != Success) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable, __glXPixmapRes); if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable, __glXWindowRes); if (pGlxWindow) pDraw = pGlxWindow->pDraw; } if (!pDraw) { client->errorValue = req->drawable; return __glXBadDrawable; } if (req->member != None) { rc = dixLookupDrawable(&pMember, req->member, client, 0, DixGetAttrAccess); if (rc != Success) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->member, __glXPixmapRes); if (pGlxPixmap) pMember = pGlxPixmap->pDraw; } if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxWindow = (__glXWindow *) LookupIDByType(req->member, __glXWindowRes); if (pGlxWindow) pMember = pGlxWindow->pDraw; } if (!pMember) { client->errorValue = req->member; return __glXBadDrawable; } } return JoinSwapGroupSGIX(pDraw, pMember); } /* ** Destroy a GL context as an X resource. */ int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; xGLXDestroyContextReq *be_req; GLXContextID gcId = req->context; __GLXcontext *glxc; int from_screen = 0; int to_screen = 0; int s; 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); from_screen = to_screen = glxc->pScreen->myNum; } else { client->errorValue = gcId; return __glXBadContext; } #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif /* * send DestroyContext request to all back-end servers */ for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); LockDisplay(dpy); GetReq(GLXDestroyContext,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXDestroyContext; be_req->context = glxc->real_ids[s-from_screen]; UnlockDisplay(dpy); SyncHandle(); } return Success; } /*****************************************************************************/ /* ** For each client, the server keeps a table of all the contexts that are ** current for that client (each thread of a client may have its own current ** context). These routines add, change, and lookup contexts in the table. */ /* ** Add a current context, and return the tag that will be used to refer to it. */ static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw) { int i; int num = cl->numCurrentContexts; __GLXcontext **table = cl->currentContexts; if (!glxc) return -1; /* ** Try to find an empty slot and use it. */ for (i=0; i < num; i++) { if (!table[i]) { table[i] = glxc; return i+1; } } /* ** Didn't find a free slot, so we'll have to grow the table. */ if (!num) { table = (__GLXcontext **) __glXMalloc(sizeof(__GLXcontext *)); cl->currentDrawables = (DrawablePtr *) __glXMalloc(sizeof(DrawablePtr)); cl->be_currentCTag = (GLXContextTag *) __glXMalloc(screenInfo.numScreens *sizeof(GLXContextTag)); } else { table = (__GLXcontext **) __glXRealloc(table, (num+1)*sizeof(__GLXcontext *)); cl->currentDrawables = (DrawablePtr *) __glXRealloc( cl->currentDrawables , (num+1)*sizeof(DrawablePtr)); cl->be_currentCTag = (GLXContextTag *) __glXRealloc(cl->be_currentCTag, (num+1)*screenInfo.numScreens*sizeof(GLXContextTag)); } table[num] = glxc; cl->currentDrawables[num] = pDraw; cl->currentContexts = table; cl->numCurrentContexts++; memset(cl->be_currentCTag + num*screenInfo.numScreens, 0, screenInfo.numScreens * sizeof(GLXContextTag)); return num+1; } /* ** Given a tag, change the current context for the corresponding entry. */ static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, GLXContextTag tag) { __GLXcontext **table = cl->currentContexts; table[tag-1] = glxc; } /* ** Given a tag, and back-end screen number, retrives the current back-end ** tag. */ int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s) { if (tag >0) { return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] ); } else { return( 0 ); } } /* ** Given a tag, and back-end screen number, sets the current back-end ** tag. */ static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag) { if (tag >0) { cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag; } } /* ** For this implementation we have chosen to simply use the index of the ** context's entry in the table as the context tag. A tag must be greater ** than 0. */ __GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) { int num = cl->numCurrentContexts; if (tag < 1 || tag > num) { return 0; } else { return cl->currentContexts[tag-1]; } } DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag) { int num = cl->numCurrentContexts; if (tag < 1 || tag > num) { return 0; } else { return cl->currentDrawables[tag-1]; } } /*****************************************************************************/ static void StopUsingContext(__GLXcontext *glxc) { if (glxc) { if (glxc == __glXLastContext) { /* Tell server GL library */ __glXLastContext = 0; } glxc->isCurrent = GL_FALSE; if (!glxc->idExists) { __glXFreeContext(glxc); } } } static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) { glxc->isCurrent = GL_TRUE; } /*****************************************************************************/ /* ** Make an OpenGL context and drawable current. */ static int MakeCurrent(__GLXclientState *cl, GLXDrawable drawable, GLXDrawable readdrawable, GLXContextID context, GLXContextTag oldContextTag) { ClientPtr client = cl->client; DrawablePtr pDraw = NULL; DrawablePtr pReadDraw = NULL; xGLXMakeCurrentReadSGIReply new_reply; xGLXMakeCurrentReq *be_req; xGLXMakeCurrentReply be_reply; xGLXMakeContextCurrentReq *be_new_req; xGLXMakeContextCurrentReply be_new_reply; GLXDrawable drawId = drawable; GLXDrawable readId = readdrawable; GLXContextID contextId = context; __GLXpixmap *pGlxPixmap = 0; __GLXpixmap *pReadGlxPixmap = 0; __GLXcontext *glxc, *prevglxc; GLXContextTag tag = oldContextTag; WindowPtr pWin = NULL; WindowPtr pReadWin = NULL; __glXWindow *pGlxWindow = NULL; __glXWindow *pGlxReadWindow = NULL; __glXPbuffer *pGlxPbuffer = NULL; __glXPbuffer *pGlxReadPbuffer = NULL; #ifdef PANORAMIX PanoramiXRes *pXinDraw = NULL; PanoramiXRes *pXinReadDraw = NULL; #endif int from_screen = 0; int to_screen = 0; int s, rc; /* ** If one is None and the other isn't, it's a bad match. */ if ((drawId == None && contextId != None) || (drawId != None && contextId == None)) { return BadMatch; } /* ** Lookup old context. If we have one, it must be in a usable state. */ if (tag != 0) { prevglxc = __glXLookupContextByTag(cl, tag); if (!prevglxc) { /* ** Tag for previous context is invalid. */ return __glXBadContextTag; } } else { prevglxc = 0; } /* ** Lookup new context. It must not be current for someone else. */ if (contextId != None) { glxc = (__GLXcontext *) LookupIDByType(contextId, __glXContextRes); if (!glxc) { client->errorValue = contextId; return __glXBadContext; } if ((glxc != prevglxc) && glxc->isCurrent) { /* Context is current to somebody else */ return BadAccess; } } else { /* Switching to no context. Ignore new drawable. */ glxc = 0; } if (drawId != None) { rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); if (rc == Success) { if (pDraw->type == DRAWABLE_WINDOW) { /* ** Drawable is an X Window. */ VisualID vid; pWin = (WindowPtr)pDraw; vid = wVisual(pWin); new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); new_reply.writeType = GLX_WINDOW_TYPE; /* ** Check if window and context are similar. */ if ((vid != glxc->pVisual->vid) || (pWin->drawable.pScreen != glxc->pScreen)) { client->errorValue = drawId; return BadMatch; } from_screen = to_screen = pWin->drawable.pScreen->myNum; } else { /* ** An X Pixmap is not allowed as a parameter (a GLX Pixmap ** is, but it must first be created with glxCreateGLXPixmap). */ client->errorValue = drawId; return __glXBadDrawable; } } if (!pDraw) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes); if (pGlxPixmap) { /* ** Check if pixmap and context are similar. */ if (pGlxPixmap->pScreen != glxc->pScreen || pGlxPixmap->pGlxVisual != glxc->pGlxVisual) { client->errorValue = drawId; return BadMatch; } pDraw = pGlxPixmap->pDraw; new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : pGlxPixmap->pGlxVisual->vid); new_reply.writeType = GLX_PIXMAP_TYPE; from_screen = to_screen = pGlxPixmap->pScreen->myNum; } } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes); if (pGlxWindow) { /* ** Drawable is a GLXWindow. ** ** Check if GLX window and context are similar. */ if (pGlxWindow->pScreen != glxc->pScreen || pGlxWindow->pGlxFBConfig != glxc->pFBConfig) { client->errorValue = drawId; return BadMatch; } pDraw = pGlxWindow->pDraw; new_reply.writeVid = pGlxWindow->pGlxFBConfig->id; new_reply.writeType = GLX_GLXWINDOW_TYPE; } } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes); if (pGlxPbuffer) { if (pGlxPbuffer->pScreen != glxc->pScreen || pGlxPbuffer->pFBConfig != glxc->pFBConfig) { client->errorValue = drawId; return BadMatch; } pDraw = (DrawablePtr)pGlxPbuffer; new_reply.writeVid = pGlxPbuffer->pFBConfig->id; new_reply.writeType = GLX_PBUFFER_TYPE; } } if (!pDraw) { /* ** Drawable is not a Window , GLXWindow or a GLXPixmap. */ client->errorValue = drawId; return __glXBadDrawable; } } else { pDraw = 0; } if (readId != None && readId != drawId ) { rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess); if (rc == Success) { if (pReadDraw->type == DRAWABLE_WINDOW) { /* ** Drawable is an X Window. */ VisualID vid; pReadWin = (WindowPtr)pDraw; vid = wVisual(pReadWin); new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); new_reply.readType = GLX_WINDOW_TYPE; /* ** Check if window and context are similar. */ if ((vid != glxc->pVisual->vid) || (pReadWin->drawable.pScreen != glxc->pScreen)) { client->errorValue = readId; return BadMatch; } } else { /* ** An X Pixmap is not allowed as a parameter (a GLX Pixmap ** is, but it must first be created with glxCreateGLXPixmap). */ client->errorValue = readId; return __glXBadDrawable; } } if (!pReadDraw) { pReadGlxPixmap = (__GLXpixmap *) LookupIDByType(readId, __glXPixmapRes); if (pReadGlxPixmap) { /* ** Check if pixmap and context are similar. */ if (pReadGlxPixmap->pScreen != glxc->pScreen || pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) { client->errorValue = readId; return BadMatch; } pReadDraw = pReadGlxPixmap->pDraw; new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : pReadGlxPixmap->pGlxVisual->vid ); new_reply.readType = GLX_PIXMAP_TYPE; } } if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxReadWindow = (__glXWindow *) LookupIDByType(readId, __glXWindowRes); if (pGlxReadWindow) { /* ** Drawable is a GLXWindow. ** ** Check if GLX window and context are similar. */ if (pGlxReadWindow->pScreen != glxc->pScreen || pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) { client->errorValue = readId; return BadMatch; } pReadDraw = pGlxReadWindow->pDraw; new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id; new_reply.readType = GLX_GLXWINDOW_TYPE; } } if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxReadPbuffer = (__glXPbuffer *)LookupIDByType(readId, __glXPbufferRes); if (pGlxReadPbuffer) { if (pGlxReadPbuffer->pScreen != glxc->pScreen || pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) { client->errorValue = drawId; return BadMatch; } pReadDraw = (DrawablePtr)pGlxReadPbuffer; new_reply.readVid = pGlxReadPbuffer->pFBConfig->id; new_reply.readType = GLX_PBUFFER_TYPE; } } if (!pReadDraw) { /* ** Drawable is neither a Window nor a GLXPixmap. */ client->errorValue = readId; return __glXBadDrawable; } } else { pReadDraw = pDraw; pReadGlxPixmap = pGlxPixmap; pReadWin = pWin; new_reply.readVid = new_reply.writeVid; new_reply.readType = new_reply.writeType; } if (prevglxc) { if (prevglxc->pGlxPixmap) { /* ** The previous drawable was a glx pixmap, release it. */ prevglxc->pGlxPixmap->refcnt--; __glXFreeGLXPixmap( prevglxc->pGlxPixmap ); prevglxc->pGlxPixmap = 0; } if (prevglxc->pGlxReadPixmap) { /* ** The previous drawable was a glx pixmap, release it. */ prevglxc->pGlxReadPixmap->refcnt--; __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap ); prevglxc->pGlxReadPixmap = 0; } if (prevglxc->pGlxWindow) { /* ** The previous drawable was a glx window, release it. */ prevglxc->pGlxWindow->refcnt--; __glXFreeGLXWindow( prevglxc->pGlxWindow ); prevglxc->pGlxWindow = 0; } if (prevglxc->pGlxReadWindow) { /* ** The previous drawable was a glx window, release it. */ prevglxc->pGlxReadWindow->refcnt--; __glXFreeGLXWindow( prevglxc->pGlxReadWindow ); prevglxc->pGlxReadWindow = 0; } if (prevglxc->pGlxPbuffer) { /* ** The previous drawable was a glx Pbuffer, release it. */ prevglxc->pGlxPbuffer->refcnt--; __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer ); prevglxc->pGlxPbuffer = 0; } if (prevglxc->pGlxReadPbuffer) { /* ** The previous drawable was a glx Pbuffer, release it. */ prevglxc->pGlxReadPbuffer->refcnt--; __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer ); prevglxc->pGlxReadPbuffer = 0; } ChangeCurrentContext(cl, glxc, tag); ChangeCurrentContext(cl, glxc, tag); StopUsingContext(prevglxc); } else { tag = AddCurrentContext(cl, glxc, pDraw); } if (glxc) { glxc->pGlxPixmap = pGlxPixmap; glxc->pGlxReadPixmap = pReadGlxPixmap; glxc->pGlxWindow = pGlxWindow; glxc->pGlxReadWindow = pGlxReadWindow; glxc->pGlxPbuffer = pGlxPbuffer; glxc->pGlxReadPbuffer = pGlxReadPbuffer; if (pGlxPixmap) { pGlxPixmap->refcnt++; } if (pReadGlxPixmap) { pReadGlxPixmap->refcnt++; } if (pGlxWindow) { pGlxWindow->refcnt++; } if (pGlxReadWindow) { pGlxReadWindow->refcnt++; } if (pGlxPbuffer) { pGlxPbuffer->refcnt++; } if (pGlxReadPbuffer) { pGlxReadPbuffer->refcnt++; } StartUsingContext(cl, glxc); new_reply.contextTag = tag; } else { new_reply.contextTag = 0; } new_reply.length = 0; new_reply.type = X_Reply; new_reply.sequenceNumber = client->sequence; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) { pXinDraw = (PanoramiXRes *) SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess); } if (pReadDraw && pReadDraw != pDraw && new_reply.readType != GLX_PBUFFER_TYPE) { pXinReadDraw = (PanoramiXRes *) SecurityLookupIDByClass(client, pReadDraw->id, XRC_DRAWABLE, DixReadAccess); } else { pXinReadDraw = pXinDraw; } } #endif /* send the MakeCurrent request to all required * back-end servers. */ for (s = from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); unsigned int be_draw = None; unsigned int be_read_draw = None; if (pGlxPixmap) { be_draw = pGlxPixmap->be_xids[s]; } else if (pGlxPbuffer) { be_draw = pGlxPbuffer->be_xids[s]; } #ifdef PANORAMIX else if (pXinDraw) { dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); } #endif else if (pGlxWindow) { pWin = (WindowPtr)pGlxWindow->pDraw; } if (pWin && be_draw == None) { be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; if (!be_draw) { /* it might be that the window did not created yet on the */ /* back-end server (lazy window creation option), force */ /* creation of the window */ dmxCreateAndRealizeWindow( pWin, TRUE ); be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; } } /* * Before sending the MakeCurrent request - sync the * X11 connection to the back-end servers to make sure * that drawable is already created */ dmxSync( dmxScreen, 1 ); if (drawId == readId) { LockDisplay(dpy); GetReq(GLXMakeCurrent, be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXMakeCurrent; be_req->drawable = be_draw; be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) { /* The make current failed */ UnlockDisplay(dpy); SyncHandle(); return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); } UnlockDisplay(dpy); SyncHandle(); SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag ); } else { if (pReadGlxPixmap) { be_read_draw = pReadGlxPixmap->be_xids[s]; } else if (pGlxReadPbuffer) { be_read_draw = pGlxReadPbuffer->be_xids[s]; } #ifdef PANORAMIX else if (pXinReadDraw) { dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client, DixReadAccess); } #endif else if (pGlxReadWindow) { pReadWin = (WindowPtr)pGlxReadWindow->pDraw; } if (pReadWin && be_read_draw == None) { be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; if (!be_read_draw) { /* it might be that the window did not created yet on the */ /* back-end server (lazy window creation option), force */ /* creation of the window */ dmxCreateAndRealizeWindow( pReadWin, TRUE ); be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; dmxSync( dmxScreen, 1 ); } } if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { LockDisplay(dpy); GetReq(GLXMakeContextCurrent, be_new_req); be_new_req->reqType = dmxScreen->glxMajorOpcode; be_new_req->glxCode = X_GLXMakeContextCurrent; be_new_req->drawable = be_draw; be_new_req->readdrawable = be_read_draw; be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) { /* The make current failed */ UnlockDisplay(dpy); SyncHandle(); return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); } UnlockDisplay(dpy); SyncHandle(); SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag ); } else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) { xGLXMakeCurrentReadSGIReq *ext_req; xGLXVendorPrivateWithReplyReq *vpreq; xGLXMakeCurrentReadSGIReply ext_reply; LockDisplay(dpy); GetReqExtra(GLXVendorPrivateWithReply, sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq, vpreq); ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq; ext_req->reqType = dmxScreen->glxMajorOpcode; ext_req->glxCode = X_GLXVendorPrivateWithReply; ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI; ext_req->drawable = be_draw; ext_req->readable = be_read_draw; ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) { /* The make current failed */ UnlockDisplay(dpy); SyncHandle(); return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); } UnlockDisplay(dpy); SyncHandle(); SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag ); } else { return BadMatch; } } XFlush( dpy ); } if (client->swapped) { __glXSwapMakeCurrentReply(client, &new_reply); } else { WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply); } return Success; } int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc) { xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; return( MakeCurrent(cl, req->drawable, req->drawable, req->context, req->oldContextTag ) ); } int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) { xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; return( MakeCurrent(cl, req->drawable, req->readdrawable, req->context, req->oldContextTag ) ); } int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) { xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; return( MakeCurrent(cl, req->drawable, req->readable, req->context, req->oldContextTag ) ); } int __glXIsDirect(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; xGLXIsDirectReply reply; __GLXcontext *glxc; /* ** Find the GL context. */ glxc = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes); if (!glxc) { client->errorValue = req->context; return __glXBadContext; } reply.isDirect = 0; reply.length = 0; reply.type = X_Reply; reply.sequenceNumber = client->sequence; if (client->swapped) { __glXSwapIsDirectReply(client, &reply); } else { WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); } return Success; } int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; /* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */ xGLXQueryVersionReply reply; /* ** Server should take into consideration the version numbers sent by the ** client if it wants to work with older clients; however, in this ** implementation the server just returns its version number. */ reply.majorVersion = __glXVersionMajor; reply.minorVersion = __glXVersionMinor; reply.length = 0; reply.type = X_Reply; reply.sequenceNumber = client->sequence; if (client->swapped) { __glXSwapQueryVersionReply(client, &reply); } else { WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); } return Success; } int __glXWaitGL(__GLXclientState *cl, GLbyte *pc) { xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc; xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc; int from_screen = 0; int to_screen = 0; int s; __GLXcontext *glxc = NULL; if (req->contextTag != 0) { glxc = __glXLookupContextByTag(cl, req->contextTag); if (glxc) { from_screen = to_screen = glxc->pScreen->myNum; } } #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); LockDisplay(dpy); GetReq(GLXWaitGL,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXWaitGL; be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); UnlockDisplay(dpy); SyncHandle(); XSync(dpy, False); } return Success; } int __glXWaitX(__GLXclientState *cl, GLbyte *pc) { xGLXWaitXReq *req = (xGLXWaitXReq *)pc; xGLXWaitXReq *be_req; int from_screen = 0; int to_screen = 0; int s; __GLXcontext *glxc = NULL; if (req->contextTag != 0) { glxc = __glXLookupContextByTag(cl, req->contextTag); if (glxc) { from_screen = to_screen = glxc->pScreen->myNum; } } #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); dmxSync( dmxScreen, 1 ); LockDisplay(dpy); GetReq(GLXWaitX,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXWaitX; be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); UnlockDisplay(dpy); SyncHandle(); XFlush( dpy ); } return Success; } int __glXCopyContext(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXCopyContextReq *be_req; xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; GLXContextID source = req->source; GLXContextID dest = req->dest; GLXContextTag tag = req->contextTag; unsigned long mask = req->mask; __GLXcontext *src, *dst; int s; int from_screen = 0; int to_screen = 0; /* ** Check that each context exists. */ src = (__GLXcontext *) LookupIDByType(source, __glXContextRes); if (!src) { client->errorValue = source; return __glXBadContext; } dst = (__GLXcontext *) LookupIDByType(dest, __glXContextRes); if (!dst) { client->errorValue = dest; return __glXBadContext; } /* ** They must be in the same address space, and same screen. */ if (src->pGlxScreen != dst->pGlxScreen) { client->errorValue = source; return BadMatch; } /* ** The destination context must not be current for any client. */ if (dst->isCurrent) { client->errorValue = dest; return BadAccess; } if (tag) { __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); if (!tagcx) { return __glXBadContextTag; } if (tagcx != src) { /* ** This would be caused by a faulty implementation of the client ** library. */ return BadMatch; } } from_screen = to_screen = src->pScreen->myNum; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); LockDisplay(dpy); GetReq(GLXCopyContext,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXCopyContext; be_req->source = (unsigned int)src->real_ids[s-from_screen]; be_req->dest = (unsigned int)dst->real_ids[s-from_screen]; be_req->mask = mask; be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); UnlockDisplay(dpy); SyncHandle(); } return Success; } int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; xGLXGetVisualConfigsReply reply; __GLXscreenInfo *pGlxScreen; __GLXvisualConfig *pGlxVisual; CARD32 buf[__GLX_TOTAL_CONFIG]; unsigned int screen; int i, p; screen = req->screen; if (screen > screenInfo.numScreens) { /* The client library must send a valid screen number. */ client->errorValue = screen; return BadValue; } pGlxScreen = &__glXActiveScreens[screen]; reply.numVisuals = pGlxScreen->numGLXVisuals; reply.numProps = __GLX_TOTAL_CONFIG; reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG) >> 2; reply.type = X_Reply; reply.sequenceNumber = client->sequence; WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); for (i=0; i < pGlxScreen->numVisuals; i++) { pGlxVisual = &pGlxScreen->pGlxVisual[i]; if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) { /* not a usable visual */ continue; } p = 0; buf[p++] = pGlxVisual->vid; buf[p++] = pGlxVisual->class; buf[p++] = pGlxVisual->rgba; buf[p++] = pGlxVisual->redSize; buf[p++] = pGlxVisual->greenSize; buf[p++] = pGlxVisual->blueSize; buf[p++] = pGlxVisual->alphaSize; buf[p++] = pGlxVisual->accumRedSize; buf[p++] = pGlxVisual->accumGreenSize; buf[p++] = pGlxVisual->accumBlueSize; buf[p++] = pGlxVisual->accumAlphaSize; buf[p++] = pGlxVisual->doubleBuffer; buf[p++] = pGlxVisual->stereo; buf[p++] = pGlxVisual->bufferSize; buf[p++] = pGlxVisual->depthSize; buf[p++] = pGlxVisual->stencilSize; buf[p++] = pGlxVisual->auxBuffers; buf[p++] = pGlxVisual->level; /* ** Add token/value pairs for extensions. */ buf[p++] = GLX_VISUAL_CAVEAT_EXT; buf[p++] = pGlxVisual->visualRating; buf[p++] = GLX_TRANSPARENT_TYPE_EXT; buf[p++] = pGlxVisual->transparentPixel; buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT; buf[p++] = pGlxVisual->transparentRed; buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT; buf[p++] = pGlxVisual->transparentGreen; buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT; buf[p++] = pGlxVisual->transparentBlue; buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT; buf[p++] = pGlxVisual->transparentAlpha; buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT; buf[p++] = pGlxVisual->transparentIndex; buf[p++] = GLX_SAMPLES_SGIS; buf[p++] = pGlxVisual->multiSampleSize; buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; buf[p++] = pGlxVisual->nMultiSampleBuffers; buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; buf[p++] = pGlxVisual->visualSelectGroup; WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, (char *)buf); } return Success; } /* ** Create a GLX Pixmap from an X Pixmap. */ static int CreateGLXPixmap(__GLXclientState *cl, VisualID visual, GLXFBConfigID fbconfigId, int screenNum, XID pixmapId, XID glxpixmapId ) { ClientPtr client = cl->client; xGLXCreateGLXPixmapReq *be_req; xGLXCreatePixmapReq *be_new_req; DrawablePtr pDraw; ScreenPtr pScreen; VisualPtr pVisual; __GLXpixmap *pGlxPixmap; __GLXscreenInfo *pGlxScreen; __GLXvisualConfig *pGlxVisual; __GLXFBConfig *pFBConfig; int i, s, rc; int from_screen, to_screen; #ifdef PANORAMIX PanoramiXRes *pXinDraw = NULL; #endif rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP, DixAddAccess); if (rc != Success) return rc; /* ** Check if screen of visual matches screen of pixmap. */ pScreen = pDraw->pScreen; if (screenNum != pScreen->myNum) { return BadMatch; } if (fbconfigId == NULL && visual == NULL) { return BadValue; } if (fbconfigId != None) { pFBConfig = glxLookupFBConfig( fbconfigId ); if (!pFBConfig) { client->errorValue = fbconfigId; return BadValue; } visual = pFBConfig->associatedVisualId; } else { pFBConfig = NULL; } if (visual != None) { /* ** Find the VisualRec for this visual. */ pVisual = pScreen->visuals; for (i=0; i < pScreen->numVisuals; i++, pVisual++) { if (pVisual->vid == visual) { break; } } if (i == pScreen->numVisuals) { client->errorValue = visual; return BadValue; } /* ** Check if depth of visual matches depth of pixmap. */ if (pVisual->nplanes != pDraw->depth) { client->errorValue = visual; return BadMatch; } /* ** Get configuration of the visual. */ pGlxScreen = &__glXActiveScreens[screenNum]; pGlxVisual = pGlxScreen->pGlxVisual; for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { if (pGlxVisual->vid == visual) { break; } } if (i == pGlxScreen->numVisuals) { /* ** Visual not support on this screen by this OpenGL implementation. */ client->errorValue = visual; return BadValue; } /* find the FBConfig for that visual (if any) */ if ( pFBConfig == NULL ) { pFBConfig = glxLookupFBConfigByVID( visual ); if ( pFBConfig == NULL ) { /* * visual does not have an FBConfig ??? client->errorValue = visual; return BadValue; */ } } } else { pVisual = NULL; pGlxVisual = NULL; } pGlxPixmap = (__GLXpixmap *) __glXMalloc(sizeof(__GLXpixmap)); if (!pGlxPixmap) { return BadAlloc; } pGlxPixmap->be_xids = (XID *) __glXMalloc(sizeof(XID) * screenInfo.numScreens); if (!pGlxPixmap->be_xids) { __glXFree( pGlxPixmap ); return BadAlloc; } pGlxPixmap->pDraw = pDraw; pGlxPixmap->pGlxScreen = pGlxScreen; pGlxPixmap->pGlxVisual = pGlxVisual; pGlxPixmap->pFBConfig = pFBConfig; pGlxPixmap->pScreen = pScreen; pGlxPixmap->idExists = True; pGlxPixmap->refcnt = 0; /* ** Bump the ref count on the X pixmap so it won't disappear. */ ((PixmapPtr) pDraw)->refcnt++; /* * send the request to the back-end server(s) */ from_screen = to_screen = screenNum; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; pXinDraw = (PanoramiXRes *) SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess); } #endif for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); Pixmap be_pixmap; DrawablePtr pRealDraw = pDraw; #ifdef PANORAMIX if (pXinDraw) { dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0, DixAddAccess); } #endif be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap; /* make sure pixmap already created on back-end */ dmxSync( dmxScreen, 1 ); if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) { __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); LockDisplay(dpy); pGlxPixmap->be_xids[s] = XAllocID(dpy); GetReq(GLXCreatePixmap,be_new_req); be_new_req->reqType = dmxScreen->glxMajorOpcode; be_new_req->glxCode = X_GLXCreatePixmap; be_new_req->screen = DefaultScreen(dpy); be_new_req->fbconfig = be_FBConfig->id; be_new_req->pixmap = (unsigned int)be_pixmap; be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; be_new_req->numAttribs = 0; UnlockDisplay(dpy); SyncHandle(); } else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) { __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req; xGLXVendorPrivateReq *vpreq; LockDisplay(dpy); pGlxPixmap->be_xids[s] = XAllocID(dpy); GetReqExtra(GLXVendorPrivate, sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq, vpreq); ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq; ext_req->reqType = dmxScreen->glxMajorOpcode; ext_req->glxCode = X_GLXVendorPrivate; ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX; ext_req->screen = DefaultScreen(dpy); ext_req->fbconfig = be_FBConfig->id; ext_req->pixmap = (unsigned int)be_pixmap; ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; UnlockDisplay(dpy); SyncHandle(); } else if (pGlxVisual) { LockDisplay(dpy); pGlxPixmap->be_xids[s] = XAllocID(dpy); GetReq(GLXCreateGLXPixmap,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXCreateGLXPixmap; be_req->screen = DefaultScreen(dpy); be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList( pGlxVisual, dmxScreen->glxVisuals, dmxScreen->numGlxVisuals ); be_req->pixmap = (unsigned int)be_pixmap; be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; UnlockDisplay(dpy); SyncHandle(); } else { client->errorValue = ( visual ? visual : fbconfigId ); __glXFree( pGlxPixmap ); return BadValue; } XFlush( dpy ); } if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) { __glXFree( pGlxPixmap ); return BadAlloc; } return Success; } int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; return( CreateGLXPixmap(cl, req->visual, None, req->screen, req->pixmap, req->glxpixmap) ); } int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; return( CreateGLXPixmap(cl, None, req->fbconfig, req->screen, req->pixmap, req->glxpixmap) ); } int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; XID glxpixmap = req->glxpixmap; __GLXpixmap *pGlxPixmap; int s; int from_screen, to_screen; /* ** Check if it's a valid GLX pixmap. */ pGlxPixmap = (__GLXpixmap *)LookupIDByType(glxpixmap, __glXPixmapRes); if (!pGlxPixmap) { client->errorValue = glxpixmap; return __glXBadPixmap; } FreeResource(glxpixmap, FALSE); /* * destroy the pixmap on the back-end server(s). */ from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); /* make sure pixmap exist in back-end */ dmxSync( dmxScreen, 1 ); LockDisplay(dpy); GetReq(GLXDestroyGLXPixmap,req); req->reqType = dmxScreen->glxMajorOpcode; req->glxCode = X_GLXDestroyGLXPixmap; req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; UnlockDisplay(dpy); SyncHandle(); } return Success; } /*****************************************************************************/ /* ** NOTE: There is no portable implementation for swap buffers as of ** this time that is of value. Consequently, this code must be ** implemented by somebody other than SGI. */ int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag) { ClientPtr client = cl->client; DrawablePtr pDraw; xGLXSwapBuffersReq *be_req; WindowPtr pWin = NULL; __GLXpixmap *pGlxPixmap = NULL; __GLXcontext *glxc = NULL; #ifdef PANORAMIX PanoramiXRes *pXinDraw = NULL; #endif __glXWindow *pGlxWindow = NULL; int from_screen = 0; int to_screen = 0; int s, rc; /* ** Check that the GLX drawable is valid. */ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); if (rc == Success) { from_screen = to_screen = pDraw->pScreen->myNum; if (pDraw->type == DRAWABLE_WINDOW) { /* ** Drawable is an X window. */ pWin = (WindowPtr)pDraw; } else { /* ** Drawable is an X pixmap, which is not allowed. */ client->errorValue = drawId; return __glXBadDrawable; } } if (!pDraw) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes); if (pGlxPixmap) { /* ** Drawable is a GLX pixmap. */ pDraw = pGlxPixmap->pDraw; from_screen = to_screen = pGlxPixmap->pScreen->myNum; } } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes); if (pGlxWindow) { /* ** Drawable is a GLXWindow. */ pDraw = pGlxWindow->pDraw; from_screen = to_screen = pGlxWindow->pScreen->myNum; } } if (!pDraw) { /* ** Drawable is neither a X window nor a GLX pixmap. */ client->errorValue = drawId; return __glXBadDrawable; } if (tag) { glxc = __glXLookupContextByTag(cl, tag); if (!glxc) { return __glXBadContextTag; } } #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; pXinDraw = (PanoramiXRes *) SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess); } #endif /* If requested, send a glFinish to all back-end servers before swapping. */ if (dmxGLXFinishSwap) { for (s=from_screen; s<=to_screen; s++) { Display *dpy = GetBackEndDisplay(cl,s); DMXScreenInfo *dmxScreen = &dmxScreens[s]; xGLXSingleReq *finishReq; xGLXSingleReply reply; #define X_GLXSingle 0 /* needed by GetReq below */ LockDisplay(dpy); GetReq(GLXSingle,finishReq); finishReq->reqType = dmxScreen->glxMajorOpcode; finishReq->glxCode = X_GLsop_Finish; finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0); (void) _XReply(dpy, (xReply*) &reply, 0, False); UnlockDisplay(dpy); SyncHandle(); } } /* If requested, send an XSync to all back-end servers before swapping. */ if (dmxGLXSyncSwap) { for (s=from_screen; s<=to_screen; s++) XSync(GetBackEndDisplay(cl,s), False); } /* send the SwapBuffers request to all back-end servers */ for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); unsigned int be_draw = 0; if (pGlxPixmap) { be_draw = (unsigned int)pGlxPixmap->be_xids[s]; } #ifdef PANORAMIX else if (pXinDraw) { dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); } #endif else if (pGlxWindow) { pWin = (WindowPtr)pGlxWindow->pDraw; } if (pWin && !be_draw) { be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; if (!be_draw) { /* it might be that the window did not created yet on the */ /* back-end server (lazy window creation option), force */ /* creation of the window */ dmxCreateAndRealizeWindow( pWin, TRUE ); be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; } } dmxSync( dmxScreen, 1 ); LockDisplay(dpy); GetReq(GLXSwapBuffers,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXSwapBuffers; be_req->drawable = be_draw; be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 ); UnlockDisplay(dpy); SyncHandle(); XFlush(dpy); } return Success; } int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; DrawablePtr pDraw; xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; GLXContextTag tag = req->contextTag; XID drawId = req->drawable; __GLXpixmap *pGlxPixmap = NULL; __GLXcontext *glxc = NULL; __glXWindow *pGlxWindow = NULL; int rc; /* ** Check that the GLX drawable is valid. */ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); if (rc == Success) { if (pDraw->type != DRAWABLE_WINDOW) { /* ** Drawable is an X pixmap, which is not allowed. */ client->errorValue = drawId; return __glXBadDrawable; } } if (!pDraw) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes); if (pGlxPixmap) { /* ** Drawable is a GLX pixmap. */ pDraw = pGlxPixmap->pDraw; } } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes); if (pGlxWindow) { /* ** Drawable is a GLXWindow. */ pDraw = pGlxWindow->pDraw; } } if (!pDraw) { /* ** Drawable is neither a X window nor a GLX pixmap. */ client->errorValue = drawId; return __glXBadDrawable; } if (tag) { glxc = __glXLookupContextByTag(cl, tag); if (!glxc) { return __glXBadContextTag; } } if (pDraw && pDraw->type == DRAWABLE_WINDOW && DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) { return SGSwapBuffers(cl, drawId, tag, pDraw); } return __glXDoSwapBuffers(cl, drawId, tag); } /************************************************************************/ /* ** Render and Renderlarge are not in the GLX API. They are used by the GLX ** client library to send batches of GL rendering commands. */ /* ** Execute all the drawing commands in a request. */ int __glXRender(__GLXclientState *cl, GLbyte *pc) { xGLXRenderReq *req; xGLXRenderReq *be_req; int size; __GLXcontext *glxc; int from_screen = 0; int to_screen = 0; int s; /* ** NOTE: much of this code also appears in the byteswapping version of this ** routine, __glXSwapRender(). Any changes made here should also be ** duplicated there. */ req = (xGLXRenderReq *) pc; glxc = __glXLookupContextByTag(cl, req->contextTag); if (!glxc) { return 0; } from_screen = to_screen = glxc->pScreen->myNum; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif pc += sz_xGLXRenderReq; size = (req->length << 2) - sz_xGLXRenderReq; /* * just forward the request to back-end server(s) */ for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); LockDisplay(dpy); GetReq(GLXRender,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXRender; be_req->length = req->length; be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); _XSend(dpy, (const char *)pc, size); UnlockDisplay(dpy); SyncHandle(); } return Success; } /* ** Execute a large rendering request (one that spans multiple X requests). */ int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc) { xGLXRenderLargeReq *req; xGLXRenderLargeReq *be_req; __GLXcontext *glxc; int from_screen = 0; int to_screen = 0; int s; /* ** NOTE: much of this code also appears in the byteswapping version of this ** routine, __glXSwapRenderLarge(). Any changes made here should also be ** duplicated there. */ req = (xGLXRenderLargeReq *) pc; glxc = __glXLookupContextByTag(cl, req->contextTag); if (!glxc) { return 0; } from_screen = to_screen = glxc->pScreen->myNum; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif pc += sz_xGLXRenderLargeReq; /* * just forward the request to back-end server(s) */ for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); GetReq(GLXRenderLarge,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXRenderLarge; be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); be_req->length = req->length; be_req->requestNumber = req->requestNumber; be_req->requestTotal = req->requestTotal; be_req->dataBytes = req->dataBytes; Data(dpy, (const char *)pc, req->dataBytes); UnlockDisplay(dpy); SyncHandle(); } return Success; } /************************************************************************/ int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc) { xGLXVendorPrivateReq *req; req = (xGLXVendorPrivateReq *) pc; switch( req->vendorCode ) { case X_GLvop_DeleteTexturesEXT: return __glXVForwardSingleReq( cl, pc ); break; case X_GLXvop_SwapIntervalSGI: if (glxIsExtensionSupported("SGI_swap_control")) { return __glXVForwardSingleReq( cl, pc ); } else { return Success; } break; #if 0 /* glx 1.3 */ case X_GLXvop_CreateGLXVideoSourceSGIX: break; case X_GLXvop_DestroyGLXVideoSourceSGIX: break; case X_GLXvop_CreateGLXPixmapWithConfigSGIX: break; case X_GLXvop_DestroyGLXPbufferSGIX: break; case X_GLXvop_ChangeDrawableAttributesSGIX: break; #endif case X_GLXvop_BindSwapBarrierSGIX: return __glXBindSwapBarrierSGIX( cl, pc ); break; case X_GLXvop_JoinSwapGroupSGIX: return __glXJoinSwapGroupSGIX( cl, pc ); break; case X_GLXvop_CreateContextWithConfigSGIX: return __glXCreateContextWithConfigSGIX( cl, pc ); break; default: /* ** unsupported private request */ cl->client->errorValue = req->vendorCode; return __glXUnsupportedPrivateRequest; } cl->client->errorValue = req->vendorCode; return __glXUnsupportedPrivateRequest; } int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) { xGLXVendorPrivateWithReplyReq *req; req = (xGLXVendorPrivateWithReplyReq *) pc; switch( req->vendorCode ) { case X_GLvop_GetConvolutionFilterEXT: case X_GLvop_GetConvolutionParameterfvEXT: case X_GLvop_GetConvolutionParameterivEXT: case X_GLvop_GetSeparableFilterEXT: case X_GLvop_GetHistogramEXT: case X_GLvop_GetHistogramParameterivEXT: case X_GLvop_GetMinmaxEXT: case X_GLvop_GetMinmaxParameterfvEXT: case X_GLvop_GetMinmaxParameterivEXT: case X_GLvop_AreTexturesResidentEXT: case X_GLvop_IsTextureEXT: return( __glXVForwardPipe0WithReply(cl, pc) ); break; case X_GLvop_GenTexturesEXT: return( __glXVForwardAllWithReply(cl, pc) ); break; #if 0 /* glx1.3 */ case X_GLvop_GetDetailTexFuncSGIS: case X_GLvop_GetSharpenTexFuncSGIS: case X_GLvop_GetColorTableSGI: case X_GLvop_GetColorTableParameterfvSGI: case X_GLvop_GetColorTableParameterivSGI: case X_GLvop_GetTexFilterFuncSGIS: case X_GLvop_GetInstrumentsSGIX: case X_GLvop_InstrumentsBufferSGIX: case X_GLvop_PollInstrumentsSGIX: case X_GLvop_FlushRasterSGIX: case X_GLXvop_CreateGLXPbufferSGIX: case X_GLXvop_GetDrawableAttributesSGIX: case X_GLXvop_QueryHyperpipeNetworkSGIX: case X_GLXvop_QueryHyperpipeConfigSGIX: case X_GLXvop_HyperpipeConfigSGIX: case X_GLXvop_DestroyHyperpipeConfigSGIX: #endif case X_GLXvop_QueryMaxSwapBarriersSGIX: return( __glXQueryMaxSwapBarriersSGIX(cl, pc) ); break; case X_GLXvop_GetFBConfigsSGIX: return( __glXGetFBConfigsSGIX(cl, pc) ); break; case X_GLXvop_MakeCurrentReadSGI: return( __glXMakeCurrentReadSGI(cl, pc) ); break; case X_GLXvop_QueryContextInfoEXT: return( __glXQueryContextInfoEXT(cl,pc) ); break; default: /* ** unsupported private request */ cl->client->errorValue = req->vendorCode; return __glXUnsupportedPrivateRequest; } } int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; xGLXQueryExtensionsStringReply reply; GLint screen; size_t length; int len, numbytes; char *be_buf; #ifdef FWD_QUERY_REQ xGLXQueryExtensionsStringReq *be_req; xGLXQueryExtensionsStringReply be_reply; DMXScreenInfo *dmxScreen; Display *dpy; int slop; #endif screen = req->screen; /* ** Check if screen exists. */ if ((screen < 0) || (screen >= screenInfo.numScreens)) { client->errorValue = screen; return BadValue; } #ifdef FWD_QUERY_REQ dmxScreen = &dmxScreens[screen]; /* Send the glXQueryServerString request */ dpy = GetBackEndDisplay(cl,screen); LockDisplay(dpy); GetReq(GLXQueryExtensionsString,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXQueryServerString; be_req->screen = DefaultScreen(dpy); _XReply(dpy, (xReply*) &be_reply, 0, False); len = (int)be_reply.length; numbytes = (int)be_reply.n; slop = numbytes * __GLX_SIZE_INT8 & 3; be_buf = (char *)malloc(numbytes); if (!be_buf) { /* Throw data on the floor */ _XEatData(dpy, len); } else { _XRead(dpy, (char *)be_buf, numbytes); if (slop) _XEatData(dpy,4-slop); } UnlockDisplay(dpy); SyncHandle(); #else be_buf = __glXGetServerString(GLX_EXTENSIONS); numbytes = strlen(be_buf) + 1; len = __GLX_PAD(numbytes) >> 2; #endif length = len; reply.type = X_Reply; reply.sequenceNumber = client->sequence; reply.length = len; reply.n = numbytes; if (client->swapped) { glxSwapQueryExtensionsStringReply(client, &reply, be_buf); } else { WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply); WriteToClient(client, (int)(length << 2), (char *)be_buf); } return Success; } int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; xGLXQueryServerStringReply reply; int name; GLint screen; size_t length; int len, numbytes; char *be_buf; #ifdef FWD_QUERY_REQ xGLXQueryServerStringReq *be_req; xGLXQueryServerStringReply be_reply; DMXScreenInfo *dmxScreen; Display *dpy; int slop; #endif name = req->name; screen = req->screen; /* ** Check if screen exists. */ if ((screen < 0) || (screen >= screenInfo.numScreens)) { client->errorValue = screen; return BadValue; } #ifdef FWD_QUERY_REQ dmxScreen = &dmxScreens[screen]; /* Send the glXQueryServerString request */ dpy = GetBackEndDisplay(cl,screen); LockDisplay(dpy); GetReq(GLXQueryServerString,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXQueryServerString; be_req->screen = DefaultScreen(dpy); be_req->name = name; _XReply(dpy, (xReply*) &be_reply, 0, False); len = (int)be_reply.length; numbytes = (int)be_reply.n; slop = numbytes * __GLX_SIZE_INT8 & 3; be_buf = (char *)malloc(numbytes); if (!be_buf) { /* Throw data on the floor */ _XEatData(dpy, len); } else { _XRead(dpy, (char *)be_buf, numbytes); if (slop) _XEatData(dpy,4-slop); } UnlockDisplay(dpy); SyncHandle(); #else be_buf = __glXGetServerString(name); numbytes = strlen(be_buf) + 1; len = __GLX_PAD(numbytes) >> 2; #endif length = len; reply.type = X_Reply; reply.sequenceNumber = client->sequence; reply.length = length; reply.n = numbytes; if (client->swapped) { glxSwapQueryServerStringReply(client, &reply, be_buf); } else { WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply); WriteToClient(client, (int)(length << 2), be_buf); } return Success; } int __glXClientInfo(__GLXclientState *cl, GLbyte *pc) { xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; xGLXClientInfoReq *be_req; const char *buf; int from_screen = 0; int to_screen = 0; int s; cl->GLClientmajorVersion = req->major; cl->GLClientminorVersion = req->minor; if (cl->GLClientextensions) __glXFree(cl->GLClientextensions); buf = (const char *)(req+1); cl->GLClientextensions = strdup(buf); to_screen = screenInfo.numScreens - 1; for (s=from_screen; s<=to_screen; s++) { DMXScreenInfo *dmxScreen = &dmxScreens[s]; Display *dpy = GetBackEndDisplay(cl,s); LockDisplay(dpy); GetReq(GLXClientInfo,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXClientInfo; be_req->major = req->major; be_req->minor = req->minor; be_req->length = req->length; be_req->numbytes = req->numbytes; Data(dpy, buf, req->numbytes); UnlockDisplay(dpy); SyncHandle(); } return Success; } int __glXUseXFont(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXUseXFontReq *req; xGLXUseXFontReq *be_req; FontPtr pFont; __GLXcontext *glxc = NULL; int from_screen = 0; int to_screen = 0; int s; dmxFontPrivPtr pFontPriv; DMXScreenInfo *dmxScreen; Display *dpy; req = (xGLXUseXFontReq *) pc; if (req->contextTag != 0) { glxc = __glXLookupContextByTag(cl, req->contextTag); if (glxc) { from_screen = to_screen = glxc->pScreen->myNum; } } /* ** Font can actually be either the ID of a font or the ID of a GC ** containing a font. */ pFont = (FontPtr)LookupIDByType(req->font, RT_FONT); if (!pFont) { GC *pGC = (GC *)LookupIDByType(req->font, RT_GC); if (!pGC) { client->errorValue = req->font; return BadFont; } pFont = pGC->font; } pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex); #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif for (s=from_screen; s<=to_screen; s++) { dmxScreen = &dmxScreens[s]; dpy = GetBackEndDisplay(cl,s); dmxSync( dmxScreen, 1 ); LockDisplay(dpy); GetReq(GLXUseXFont,be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXUseXFont; be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); be_req->font = pFontPriv->font[s]->fid; be_req->first = req->first; be_req->count = req->count; be_req->listBase = req->listBase; UnlockDisplay(dpy); SyncHandle(); XSync( dpy, False ); } return Success; } /* * start GLX 1.3 here */ int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; xGLXGetFBConfigsReply reply; __GLXFBConfig *pFBConfig; CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS]; int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS; unsigned int screen = req->screen; int numFBConfigs, i, p; __GLXscreenInfo *pGlxScreen; if (screen > screenInfo.numScreens) { /* The client library must send a valid screen number. */ client->errorValue = screen; return BadValue; } pGlxScreen = &__glXActiveScreens[screen]; numFBConfigs = __glXNumFBConfigs; reply.numFBConfigs = numFBConfigs; reply.numAttribs = numAttribs; reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2; reply.type = X_Reply; reply.sequenceNumber = client->sequence; if (client->swapped) { __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.numFBConfigs); __GLX_SWAP_INT(&reply.numAttribs); } WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); for (i=0; i < numFBConfigs; i++) { int associatedVisualId = 0; int drawableTypeIndex; pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ]; p = 0; /* core attributes */ buf[p++] = GLX_FBCONFIG_ID; buf[p++] = pFBConfig->id; buf[p++] = GLX_BUFFER_SIZE; buf[p++] = pFBConfig->indexBits; buf[p++] = GLX_LEVEL; buf[p++] = pFBConfig->level; buf[p++] = GLX_DOUBLEBUFFER; buf[p++] = pFBConfig->doubleBufferMode; buf[p++] = GLX_STEREO; buf[p++] = pFBConfig->stereoMode; buf[p++] = GLX_AUX_BUFFERS; buf[p++] = pFBConfig->maxAuxBuffers; buf[p++] = GLX_RED_SIZE; buf[p++] = pFBConfig->redBits; buf[p++] = GLX_GREEN_SIZE; buf[p++] = pFBConfig->greenBits; buf[p++] = GLX_BLUE_SIZE; buf[p++] = pFBConfig->blueBits; buf[p++] = GLX_ALPHA_SIZE; buf[p++] = pFBConfig->alphaBits; buf[p++] = GLX_DEPTH_SIZE; buf[p++] = pFBConfig->depthBits; buf[p++] = GLX_STENCIL_SIZE; buf[p++] = pFBConfig->stencilBits; buf[p++] = GLX_ACCUM_RED_SIZE; buf[p++] = pFBConfig->accumRedBits; buf[p++] = GLX_ACCUM_GREEN_SIZE; buf[p++] = pFBConfig->accumGreenBits; buf[p++] = GLX_ACCUM_BLUE_SIZE; buf[p++] = pFBConfig->accumBlueBits; buf[p++] = GLX_ACCUM_ALPHA_SIZE; buf[p++] = pFBConfig->accumAlphaBits; buf[p++] = GLX_RENDER_TYPE; buf[p++] = pFBConfig->renderType; buf[p++] = GLX_DRAWABLE_TYPE; drawableTypeIndex = p; buf[p++] = pFBConfig->drawableType; buf[p++] = GLX_X_VISUAL_TYPE; buf[p++] = pFBConfig->visualType; buf[p++] = GLX_CONFIG_CAVEAT; buf[p++] = pFBConfig->visualCaveat; buf[p++] = GLX_TRANSPARENT_TYPE; buf[p++] = pFBConfig->transparentType; buf[p++] = GLX_TRANSPARENT_RED_VALUE; buf[p++] = pFBConfig->transparentRed; buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; buf[p++] = pFBConfig->transparentGreen; buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; buf[p++] = pFBConfig->transparentBlue; buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; buf[p++] = pFBConfig->transparentAlpha; buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; buf[p++] = pFBConfig->transparentIndex; buf[p++] = GLX_MAX_PBUFFER_WIDTH; buf[p++] = pFBConfig->maxPbufferWidth; buf[p++] = GLX_MAX_PBUFFER_HEIGHT; buf[p++] = pFBConfig->maxPbufferHeight; buf[p++] = GLX_MAX_PBUFFER_PIXELS; buf[p++] = pFBConfig->maxPbufferPixels; /* * find the visual of the back-end server and match a visual * on the proxy. * do only once - if a visual is not yet associated. */ if (pFBConfig->associatedVisualId == (unsigned int)-1) { DMXScreenInfo *dmxScreen = &dmxScreens[screen]; __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ]; __GLXvisualConfig *pGlxVisual = NULL; int v; int found = 0; for (v=0; vnumGlxVisuals; v++) { if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) { pGlxVisual = &dmxScreen->glxVisuals[v]; break; } } if (pGlxVisual) { for (v=0; vnumVisuals; v++) { if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) { associatedVisualId = pGlxScreen->pGlxVisual[v].vid; found = 1; break; } } } if (!found) { associatedVisualId = 0; pFBConfig->drawableType &= ~(GLX_WINDOW_BIT); buf[drawableTypeIndex] = pFBConfig->drawableType; } #ifdef PANORAMIX else if (!noPanoramiXExtension) { /* convert the associated visualId to the panoramix one */ pFBConfig->associatedVisualId = PanoramiXTranslateVisualID(screen, v); } #endif } else { associatedVisualId = pFBConfig->associatedVisualId; } buf[p++] = GLX_VISUAL_ID; buf[p++] = associatedVisualId; /* SGIS_multisample attributes */ buf[p++] = GLX_SAMPLES_SGIS; buf[p++] = pFBConfig->multiSampleSize; buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; buf[p++] = pFBConfig->nMultiSampleBuffers; /* SGIX_pbuffer specific attributes */ buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX; buf[p++] = pFBConfig->optimalPbufferWidth; buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX; buf[p++] = pFBConfig->optimalPbufferHeight; buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; buf[p++] = pFBConfig->visualSelectGroup; if (client->swapped) { __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs); } WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf); } return Success; } int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc; xGLXGetFBConfigsReq new_req; new_req.reqType = req->reqType; new_req.glxCode = req->glxCode; new_req.length = req->length; new_req.screen = req->screen; return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) ); } int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; int screen = req->screen; GLXFBConfigID fbconfigId = req->fbconfig; XID windowId = req->window; XID glxwindowId = req->glxwindow; DrawablePtr pDraw; ScreenPtr pScreen; __glXWindow *pGlxWindow; __GLXFBConfig *pGlxFBConfig = NULL; VisualPtr pVisual; VisualID visId; int i, rc; /* ** Check if windowId is valid */ rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW, DixAddAccess); if (rc != Success) return rc; /* ** Check if screen of window matches screen of fbconfig. */ pScreen = pDraw->pScreen; if (screen != pScreen->myNum) { return BadMatch; } /* ** Find the FBConfigRec for this fbconfigid. */ if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { client->errorValue = fbconfigId; return __glXBadFBConfig; } visId = pGlxFBConfig->associatedVisualId; /* ** Check if the fbconfig supports rendering to windows */ if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) { return BadMatch; } if (visId != None) { /* ** Check if the visual ID is valid for this screen. */ pVisual = pScreen->visuals; for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { if (pVisual->vid == visId) { break; } } if (i == pScreen->numVisuals) { client->errorValue = visId; return BadValue; } /* ** Check if color buffer depth of fbconfig matches depth ** of window. */ if (pVisual->nplanes != pDraw->depth) { return BadMatch; } } else /* ** The window was created with no visual that corresponds ** to fbconfig */ return BadMatch; /* ** Check if there is already a fbconfig associated with this window */ if ( LookupIDByType(glxwindowId, __glXWindowRes) ) { client->errorValue = glxwindowId; return BadAlloc; } pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow)); if (!pGlxWindow) { return BadAlloc; } /* ** Register this GLX window as a resource */ if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) { return BadAlloc; } pGlxWindow->pDraw = pDraw; pGlxWindow->type = GLX_GLXWINDOW_TYPE; pGlxWindow->idExists = True; pGlxWindow->refcnt = 0; pGlxWindow->pGlxFBConfig = pGlxFBConfig; pGlxWindow->pScreen = pScreen; return Success; } int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; XID glxwindow = req->glxwindow; /* ** Check if it's a valid GLX window. */ if (!LookupIDByType(glxwindow, __glXWindowRes)) { client->errorValue = glxwindow; return __glXBadDrawable; } /* ** The glx window destructor will check whether it's current before ** freeing anything. */ FreeResource(glxwindow, RT_NONE); return Success; } int __glXQueryContext(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; __GLXcontext *ctx; xGLXQueryContextReq *req; xGLXQueryContextReply reply; int nProps; int *sendBuf, *pSendBuf; int nReplyBytes; req = (xGLXQueryContextReq *)pc; ctx = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes); if (!ctx) { client->errorValue = req->context; return __glXBadContext; } nProps = 3; reply.length = nProps << 1; reply.type = X_Reply; reply.sequenceNumber = client->sequence; reply.n = nProps; nReplyBytes = reply.length << 2; sendBuf = (int *)malloc(nReplyBytes); pSendBuf = sendBuf; *pSendBuf++ = GLX_FBCONFIG_ID; *pSendBuf++ = (int)(ctx->pFBConfig->id); *pSendBuf++ = GLX_RENDER_TYPE; *pSendBuf++ = (int)(ctx->pFBConfig->renderType); *pSendBuf++ = GLX_SCREEN; *pSendBuf++ = (int)(ctx->pScreen->myNum); if (client->swapped) { __glXSwapQueryContextReply(client, &reply, sendBuf); } else { WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply); WriteToClient(client, nReplyBytes, (char *)sendBuf); } free((char *)sendBuf); return Success; } int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; __GLXcontext *ctx; xGLXQueryContextInfoEXTReq *req; xGLXQueryContextInfoEXTReply reply; int nProps; int *sendBuf, *pSendBuf; int nReplyBytes; req = (xGLXQueryContextInfoEXTReq *)pc; ctx = (__GLXcontext *) SecurityLookupIDByType(client, req->context, __glXContextRes, DixReadAccess); if (!ctx) { client->errorValue = req->context; return __glXBadContext; } nProps = 4; reply.length = nProps << 1; reply.type = X_Reply; reply.sequenceNumber = client->sequence; reply.n = nProps; nReplyBytes = reply.length << 2; sendBuf = (int *)malloc(nReplyBytes); pSendBuf = sendBuf; *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; *pSendBuf++ = (int)(ctx->share_id); *pSendBuf++ = GLX_VISUAL_ID_EXT; *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0); *pSendBuf++ = GLX_SCREEN_EXT; *pSendBuf++ = (int)(ctx->pScreen->myNum); *pSendBuf++ = GLX_FBCONFIG_ID; *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0); if (client->swapped) { __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf); } else { WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply); WriteToClient(client, nReplyBytes, (char *)sendBuf); } free((char *)sendBuf); return Success; } int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc; xGLXCreatePbufferReq *be_req; int screen = req->screen; GLXFBConfigID fbconfigId = req->fbconfig; GLXPbuffer pbuffer = req->pbuffer; __glXPbuffer *pGlxPbuffer; int numAttribs = req->numAttribs; int *attr; ScreenPtr pScreen; __GLXFBConfig *pGlxFBConfig; __GLXFBConfig *be_pGlxFBConfig; XID be_xid; Display *dpy; DMXScreenInfo *dmxScreen; int s; int from_screen, to_screen; /* ** Look up screen and FBConfig. */ if (screen > screenInfo.numScreens) { /* The client library must send a valid screen number. */ client->errorValue = screen; return BadValue; } pScreen = screenInfo.screens[screen]; /* ** Find the FBConfigRec for this fbconfigid. */ if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { client->errorValue = fbconfigId; return __glXBadFBConfig; } /* ** Create the GLX part of the Pbuffer. */ pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer)); if (!pGlxPbuffer) { return BadAlloc; } pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens ); if (!pGlxPbuffer->be_xids) { free(pGlxPbuffer); return BadAlloc; } /* * Allocate an XID on the back-end server(s) and send him the request */ from_screen = to_screen = screen; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif for (s=from_screen; s<=to_screen; s++) { dpy = GetBackEndDisplay(cl,s); be_xid = XAllocID(dpy); dmxScreen = &dmxScreens[s]; be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s ); attr = (int *)( req+1 ); LockDisplay(dpy); GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXCreatePbuffer; be_req->screen = be_pGlxFBConfig->screen; be_req->fbconfig = be_pGlxFBConfig->id; be_req->pbuffer = be_xid; be_req->numAttribs = numAttribs; /* Send attributes */ if ( attr != NULL ) { CARD32 *pc = (CARD32 *)(be_req + 1); while (numAttribs-- > 0) { *pc++ = *attr++; /* token */ *pc++ = *attr++; /* value */ } } UnlockDisplay(dpy); SyncHandle(); pGlxPbuffer->be_xids[s] = be_xid; } pGlxPbuffer->idExists = True; pGlxPbuffer->refcnt = 0; pGlxPbuffer->pFBConfig = pGlxFBConfig; pGlxPbuffer->pScreen = pScreen; /* ** Register the resource. */ if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) { return BadAlloc; } return Success; } int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; xGLXDestroyPbufferReq *be_req; GLXPbuffer pbuffer = req->pbuffer; Display *dpy; int screen; DMXScreenInfo *dmxScreen; __glXPbuffer *pGlxPbuffer; int s; int from_screen, to_screen; /* ** Check if it's a valid Pbuffer */ pGlxPbuffer = (__glXPbuffer *)LookupIDByType(pbuffer, __glXPbufferRes); if (!pGlxPbuffer) { client->errorValue = pbuffer; return __glXBadPbuffer; } screen = pGlxPbuffer->pScreen->myNum; from_screen = to_screen = screen; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif for (s=from_screen; s<=to_screen; s++) { dpy = GetBackEndDisplay(cl,s); dmxScreen = &dmxScreens[s]; /* send the destroy request to the back-end server */ LockDisplay(dpy); GetReq(GLXDestroyPbuffer, be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXDestroyPbuffer; be_req->pbuffer = pGlxPbuffer->be_xids[s]; UnlockDisplay(dpy); SyncHandle(); } FreeResource(pbuffer, RT_NONE); return Success; } int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) { xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; xGLXGetDrawableAttributesReq *be_req; xGLXGetDrawableAttributesReply reply; ClientPtr client = cl->client; GLXDrawable drawId = req->drawable; GLXDrawable be_drawable = 0; DrawablePtr pDraw = NULL; Display *dpy; int screen, rc; DMXScreenInfo *dmxScreen; CARD32 *attribs = NULL; int attribs_size; #ifdef PANORAMIX PanoramiXRes *pXinDraw = NULL; #endif if (drawId != None) { rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); if (rc == Success) { if (pDraw->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDraw; be_drawable = 0; screen = pWin->drawable.pScreen->myNum; } else { /* ** Drawable is not a Window , GLXWindow or a GLXPixmap. */ client->errorValue = drawId; return __glXBadDrawable; } } if (!pDraw) { __GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes); if (pGlxPixmap) { pDraw = pGlxPixmap->pDraw; screen = pGlxPixmap->pScreen->myNum; be_drawable = pGlxPixmap->be_xids[screen]; } } if (!pDraw) { __glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes); if (pGlxWindow) { pDraw = pGlxWindow->pDraw; screen = pGlxWindow->pScreen->myNum; be_drawable = 0; } } if (!pDraw) { __glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes); if (pGlxPbuffer) { pDraw = (DrawablePtr)pGlxPbuffer; screen = pGlxPbuffer->pScreen->myNum; be_drawable = pGlxPbuffer->be_xids[screen]; } } if (!pDraw) { /* ** Drawable is not a Window , GLXWindow or a GLXPixmap. */ client->errorValue = drawId; return __glXBadDrawable; } } /* if the drawable is a window or GLXWindow - * we need to find the base id on the back-end server */ if (!be_drawable) { WindowPtr pWin = (WindowPtr)pDraw; #ifdef PANORAMIX if (!noPanoramiXExtension) { pXinDraw = (PanoramiXRes *) SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess); if (!pXinDraw) { client->errorValue = drawId; return __glXBadDrawable; } dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, DixReadAccess); } #endif if (pWin) { be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; if (!be_drawable) { /* it might be that the window did not created yet on the */ /* back-end server (lazy window creation option), force */ /* creation of the window */ dmxCreateAndRealizeWindow( pWin, TRUE ); be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; } } else { client->errorValue = drawId; return __glXBadDrawable; } } /* send the request to the back-end server */ dpy = GetBackEndDisplay(cl,screen); dmxScreen = &dmxScreens[screen]; /* make sure drawable exists on back-end */ dmxSync( dmxScreen, 1 ); LockDisplay(dpy); GetReq(GLXGetDrawableAttributes, be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXGetDrawableAttributes; be_req->drawable = be_drawable; be_req->length = req->length; if (!_XReply(dpy, (xReply *) &reply, 0, False)) { UnlockDisplay(dpy); SyncHandle(); return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); } if (reply.numAttribs) { attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32; attribs = (CARD32 *) malloc(attribs_size); if (attribs == NULL) { UnlockDisplay(dpy); SyncHandle(); return BadAlloc; } _XRead(dpy, (char *) attribs, attribs_size); } UnlockDisplay(dpy); SyncHandle(); /* send the reply back to the client */ reply.sequenceNumber = client->sequence; if (client->swapped) { __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs); } else { WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply); WriteToClient(client, attribs_size, (char *)attribs); } Xfree(attribs); return Success; } int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) { xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc; xGLXChangeDrawableAttributesReq *be_req; ClientPtr client = cl->client; GLXDrawable drawId = req->drawable; GLXDrawable be_drawable = 0; DrawablePtr pDraw = NULL; Display *dpy; int screen, rc; DMXScreenInfo *dmxScreen; char *attrbuf; #ifdef PANORAMIX PanoramiXRes *pXinDraw = NULL; PanoramiXRes *pXinReadDraw = NULL; #endif if (drawId != None) { rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess); if (rc == Success) { if (pDraw->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDraw; be_drawable = 0; screen = pWin->drawable.pScreen->myNum; } else { /* ** Drawable is not a Window , GLXWindow or a GLXPixmap. */ client->errorValue = drawId; return __glXBadDrawable; } } if (!pDraw) { __GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes); if (pGlxPixmap) { pDraw = pGlxPixmap->pDraw; screen = pGlxPixmap->pScreen->myNum; be_drawable = pGlxPixmap->be_xids[screen]; } } if (!pDraw) { __glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes); if (pGlxWindow) { pDraw = pGlxWindow->pDraw; screen = pGlxWindow->pScreen->myNum; be_drawable = 0; } } if (!pDraw) { __glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes); if (pGlxPbuffer) { pDraw = (DrawablePtr)pGlxPbuffer; screen = pGlxPbuffer->pScreen->myNum; be_drawable = pGlxPbuffer->be_xids[screen]; } } if (!pDraw) { /* ** Drawable is not a Window , GLXWindow or a GLXPixmap. */ client->errorValue = drawId; return __glXBadDrawable; } } /* if the drawable is a window or GLXWindow - * we need to find the base id on the back-end server */ if (!be_drawable) { WindowPtr pWin = (WindowPtr)pDraw; #ifdef PANORAMIX if (!noPanoramiXExtension) { pXinDraw = (PanoramiXRes *) SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess); if (!pXinDraw) { client->errorValue = drawId; return __glXBadDrawable; } dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, DixReadAccess); } #endif if (pWin) { be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; if (!be_drawable) { /* it might be that the window did not created yet on the */ /* back-end server (lazy window creation option), force */ /* creation of the window */ dmxCreateAndRealizeWindow( pWin, TRUE ); be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; } } else { client->errorValue = drawId; return __glXBadDrawable; } } /* send the request to the back-end server */ dpy = GetBackEndDisplay(cl,screen); dmxScreen = &dmxScreens[screen]; /* make sure drawable exists on back-end */ dmxSync( dmxScreen, 1 ); LockDisplay(dpy); GetReqExtra(GLXChangeDrawableAttributes, 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req); be_req->reqType = dmxScreen->glxMajorOpcode; be_req->glxCode = X_GLXChangeDrawableAttributes; be_req->drawable = be_drawable; be_req->numAttribs = req->numAttribs; be_req->length = req->length; UnlockDisplay(dpy); SyncHandle(); return Success; } int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag) { ClientPtr client = cl->client; xGLXRenderLargeReq *req; GLint maxSize, amount; GLint totalRequests, requestNumber; GLint dataLen; GLbyte *data; __GLXcontext *glxc; int s; int from_screen, to_screen; maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq); dataLen = cl->largeCmdBytesTotal; totalRequests = (dataLen / maxSize); if (dataLen % maxSize) totalRequests++; glxc = __glXLookupContextByTag(cl, contextTag); if (!glxc) { client->errorValue = contextTag; return __glXBadContext; } from_screen = to_screen = glxc->pScreen->myNum; #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; } #endif /* ** Send enough requests until the whole array is sent. */ requestNumber = 1; data = cl->largeCmdBuf; while (dataLen > 0) { amount = dataLen; if (amount > maxSize) { amount = maxSize; } for (s=from_screen; s<=to_screen; s++) { Display *dpy = GetBackEndDisplay(cl,s); DMXScreenInfo *dmxScreen = &dmxScreens[s]; LockDisplay(dpy); GetReq(GLXRenderLarge,req); req->reqType = dmxScreen->glxMajorOpcode; req->glxCode = X_GLXRenderLarge; req->contextTag = GetCurrentBackEndTag(cl,contextTag,s); req->length += (amount + 3) >> 2; req->requestNumber = requestNumber++; req->requestTotal = totalRequests; req->dataBytes = amount; Data(dpy, ((const char*)data), amount); dataLen -= amount; data = ((GLbyte *) data) + amount; UnlockDisplay(dpy); SyncHandle(); } } return Success; }