/* * 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" #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" #include "glxcmds.h" #ifdef PANORAMIX #include "panoramiXsrv.h" #endif extern __GLXFBConfig **__glXFBConfigs; extern int __glXNumFBConfigs; extern int __glXGetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc); #define BE_TO_CLIENT_ERROR(x) \ ( (x) >= __glXerrorBase ? \ (x) - dmxScreen->glxErrorBase + __glXerrorBase \ : (x) ) static __GLXFBConfig * glxLookupFBConfig(GLXFBConfigID id) { int i, j; for (i = 0, j = 0; i < __glXNumFBConfigs; i++, j += (__glXNumActiveScreens + 1)) { if (__glXFBConfigs[j]->id == id) return __glXFBConfigs[j]; } return NULL; } static __GLXFBConfig * glxLookupFBConfigByVID(VisualID vid) { int i, j; for (i = 0, j = 0; i < __glXNumFBConfigs; i++, j += (__glXNumActiveScreens + 1)) { if (__glXFBConfigs[j]->associatedVisualId == vid) return __glXFBConfigs[j]; } return NULL; } static __GLXFBConfig * glxLookupBackEndFBConfig(GLXFBConfigID id, int screen) { int i; int j; for (i = 0, j = 0; i < __glXNumFBConfigs; i++, j += (__glXNumActiveScreens + 1)) { if (__glXFBConfigs[j]->id == id) return __glXFBConfigs[j + screen + 1]; } return NULL; } 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]; } /** * Convert the render type bits from fbconfig into context render type. */ static int renderTypeBitsToRenderTypeEnum(int fbRenderType) { if (fbRenderType & GLX_RGBA_BIT) return GLX_RGBA_TYPE; if (fbRenderType & GLX_COLOR_INDEX_BIT) return GLX_COLOR_INDEX_TYPE; if (fbRenderType & GLX_RGBA_FLOAT_BIT_ARB) return GLX_RGBA_FLOAT_TYPE_ARB; if (fbRenderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) return GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT; /* There's no recognized renderType in the config */ return GLX_RGBA_TYPE; } /* ** 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 = 0; GLXFBConfigID be_fbconfigId = 0; 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 { dixLookupResourceByType((void **) &shareglxc, shareList, __glXContextRes, NullClient, DixUnknownAccess); if (!shareglxc) { client->errorValue = shareList; return __glXBadContext; } } /* ** Allocate memory for the new context */ glxc = calloc(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; free(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; free(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; free(glxc); return BadValue; } if (glxc->pFBConfig == NULL) { glxc->pFBConfig = glxLookupFBConfigByVID(visual); if (glxc->pFBConfig == NULL) { /* * visual does not have an FBConfig ??? client->errorValue = visual; free( 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 *) malloc(sizeof(XID) * num_be_screens); if (!glxc->real_ids) { return BadAlloc; } glxc->real_vids = (XID *) malloc(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 */ free(glxc->real_ids); free(glxc->real_vids); free(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) { /* For a specific visual, multiple render types (i.e., both RGB * and COLOR INDEX) can be accessible. The only parameter to * choose the renderType should be the class of the colormap, * since the first classes do not support RGB mode (only COLOR * INDEX), and TrueColor and DirectColor do not support COLOR * INDEX. */ int renderType = GLX_RGBA_TYPE; 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; } } else { renderType = renderTypeBitsToRenderTypeEnum(glxc->pFBConfig->renderType); } 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, (void *) glxc)) { free(glxc->real_ids); free(glxc->real_vids); free(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 = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .max = QueryMaxSwapBarriersSGIX(req->screen) }; if (client->swapped) { __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply); } else { WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, &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) { dixLookupResourceByType((void **) &pGlxPixmap, req->drawable, __glXPixmapRes, NullClient, DixUnknownAccess); if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) { dixLookupResourceByType((void **) &pGlxWindow, req->drawable, __glXWindowRes, NullClient, DixUnknownAccess); 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) { dixLookupResourceByType((void **) &pGlxPixmap, req->drawable, __glXPixmapRes, NullClient, DixUnknownAccess); if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) { dixLookupResourceByType((void **) &pGlxWindow, req->drawable, __glXWindowRes, NullClient, DixUnknownAccess); 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) { dixLookupResourceByType((void **) &pGlxPixmap, req->member, __glXPixmapRes, NullClient, DixUnknownAccess); if (pGlxPixmap) pMember = pGlxPixmap->pDraw; } if (!pMember && __GLX_IS_VERSION_SUPPORTED(1, 3)) { dixLookupResourceByType((void **) &pGlxWindow, req->member, __glXWindowRes, NullClient, DixUnknownAccess); 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; dixLookupResourceByType((void **) &glxc, gcId, __glXContextRes, NullClient, DixUnknownAccess); 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 **) malloc(sizeof(__GLXcontext *)); cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr)); cl->be_currentCTag = (GLXContextTag *) malloc(screenInfo.numScreens * sizeof(GLXContextTag)); } else { table = (__GLXcontext **) realloc(table, (num + 1) * sizeof(__GLXcontext *)); cl->currentDrawables = (DrawablePtr *) realloc(cl->currentDrawables, (num + 1) * sizeof(DrawablePtr)); cl->be_currentCTag = (GLXContextTag *) realloc(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 = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; 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) { dixLookupResourceByType((void **) &glxc, contextId, __glXContextRes, NullClient, DixUnknownAccess); 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) { dixLookupResourceByType((void **) &pGlxPixmap, drawId, __glXPixmapRes, NullClient, DixUnknownAccess); 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)) { dixLookupResourceByType((void **) &pGlxWindow, drawId, __glXWindowRes, NullClient, DixUnknownAccess); 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)) { dixLookupResourceByType((void **) &pGlxPbuffer, drawId, __glXPbufferRes, NullClient, DixUnknownAccess); 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) { dixLookupResourceByType((void **) &pReadGlxPixmap, readId, __glXPixmapRes, NullClient, DixUnknownAccess); 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)) { dixLookupResourceByType((void **) &pGlxReadWindow, readId, __glXWindowRes, NullClient, DixUnknownAccess); 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)) { dixLookupResourceByType((void **) &pGlxReadPbuffer, readId, __glXPbufferRes, NullClient, DixUnknownAccess); 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; } #ifdef PANORAMIX if (!noPanoramiXExtension) { from_screen = 0; to_screen = screenInfo.numScreens - 1; if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) { dixLookupResourceByClass((void **) &pXinDraw, pDraw->id, XRC_DRAWABLE, client, DixReadAccess); } if (pReadDraw && pReadDraw != pDraw && new_reply.readType != GLX_PBUFFER_TYPE) { dixLookupResourceByClass((void **) &pXinReadDraw, pReadDraw->id, XRC_DRAWABLE, client, 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, &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. */ dixLookupResourceByType((void **) &glxc, req->context, __glXContextRes, NullClient, DixUnknownAccess); if (!glxc) { client->errorValue = req->context; return __glXBadContext; } reply = (xGLXIsDirectReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .isDirect = 0 }; if (client->swapped) { __glXSwapIsDirectReply(client, &reply); } else { WriteToClient(client, sz_xGLXIsDirectReply, &reply); } return Success; } int __glXQueryVersion(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; /* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */ xGLXQueryVersionReply reply = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, /* ** 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. */ .majorVersion = __glXVersionMajor, .minorVersion = __glXVersionMinor }; if (client->swapped) { __glXSwapQueryVersionReply(client, &reply); } else { WriteToClient(client, sz_xGLXQueryVersionReply, &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. */ dixLookupResourceByType((void **) &src, source, __glXContextRes, NullClient, DixUnknownAccess); if (!src) { client->errorValue = source; return __glXBadContext; } dixLookupResourceByType((void **) &dst, dest, __glXContextRes, NullClient, DixUnknownAccess); 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 = (xGLXGetVisualConfigsReply) { .type = X_Reply, .sequenceNumber = client->sequence, .numVisuals = pGlxScreen->numGLXVisuals, .numProps = __GLX_TOTAL_CONFIG, .length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG) >> 2 }; WriteToClient(client, sz_xGLXGetVisualConfigsReply, &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, 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 == 0 && visual == 0) { 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; pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum]; } pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap)); if (!pGlxPixmap) { return BadAlloc; } pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens); if (!pGlxPixmap->be_xids) { free(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; dixLookupResourceByClass((void **) &pXinDraw, pDraw->id, XRC_DRAWABLE, client, 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); free(pGlxPixmap->be_xids); free(pGlxPixmap); return BadValue; } XFlush(dpy); } if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) { free(pGlxPixmap->be_xids); free(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. */ dixLookupResourceByType((void **) &pGlxPixmap, glxpixmap, __glXPixmapRes, NullClient, DixUnknownAccess); 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) { dixLookupResourceByType((void **) &pGlxPixmap, drawId, __glXPixmapRes, NullClient, DixUnknownAccess); 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)) { dixLookupResourceByType((void **) &pGlxWindow, drawId, __glXWindowRes, NullClient, DixUnknownAccess); 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; dixLookupResourceByClass((void **) &pXinDraw, pDraw->id, XRC_DRAWABLE, client, 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) { dixLookupResourceByType((void **) &pGlxPixmap, drawId, __glXPixmapRes, NullClient, DixUnknownAccess); if (pGlxPixmap) { /* ** Drawable is a GLX pixmap. */ pDraw = pGlxPixmap->pDraw; } } if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) { dixLookupResourceByType((void **) &pGlxWindow, drawId, __glXWindowRes, NullClient, DixUnknownAccess); 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; #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; be_buf = (char *) malloc(numbytes); if (!be_buf) { /* Throw data on the floor */ _XEatDataWords(dpy, len); } else { _XReadPad(dpy, (char *) be_buf, numbytes); } UnlockDisplay(dpy); SyncHandle(); #else be_buf = __glXGetServerString(GLX_EXTENSIONS); numbytes = strlen(be_buf) + 1; len = __GLX_PAD(numbytes) >> 2; #endif length = len; reply = (xGLXQueryExtensionsStringReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = len, .n = numbytes }; if (client->swapped) { glxSwapQueryExtensionsStringReply(client, &reply, be_buf); } else { WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply); WriteToClient(client, (int) (length << 2), 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; #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; be_buf = (char *) malloc(numbytes); if (!be_buf) { /* Throw data on the floor */ _XEatDataWords(dpy, len); } else { _XReadPad(dpy, (char *) be_buf, numbytes); } UnlockDisplay(dpy); SyncHandle(); #else be_buf = __glXGetServerString(name); numbytes = strlen(be_buf) + 1; len = __GLX_PAD(numbytes) >> 2; #endif length = len; reply = (xGLXQueryServerStringReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = length, .n = numbytes }; if (client->swapped) { glxSwapQueryServerStringReply(client, &reply, be_buf); } else { WriteToClient(client, sz_xGLXQueryServerStringReply, &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; free(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. */ dixLookupResourceByType((void **) &pFont, req->font, RT_FONT, NullClient, DixUnknownAccess); if (!pFont) { GC *pGC; dixLookupResourceByType((void **) &pGC, req->font, RT_GC, NullClient, DixUnknownAccess); 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 = (xGLXGetFBConfigsReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2, .numFBConfigs = numFBConfigs, .numAttribs = numAttribs }; 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, &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; v < dmxScreen->numGlxVisuals; v++) { if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) { pGlxVisual = &dmxScreen->glxVisuals[v]; break; } } if (pGlxVisual) { for (v = 0; v < pGlxScreen->numVisuals; 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_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_INT_ARRAY((int *) buf, 2 * numAttribs); } WriteToClient(client, 2 * numAttribs * __GLX_SIZE_CARD32, 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; void *val; /* ** 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 (Success == dixLookupResourceByType(&val, glxwindowId, __glXWindowRes, NullClient, DixUnknownAccess)) { 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; void *val; /* ** Check if it's a valid GLX window. */ if (Success != dixLookupResourceByType(&val, glxwindow, __glXWindowRes, NullClient, DixUnknownAccess)) { 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; dixLookupResourceByType((void **) &ctx, req->context, __glXContextRes, NullClient, DixUnknownAccess); if (!ctx) { client->errorValue = req->context; return __glXBadContext; } nProps = 3; reply = (xGLXQueryContextReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = nProps << 1, .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++ = renderTypeBitsToRenderTypeEnum(ctx->pFBConfig->renderType); *pSendBuf++ = GLX_SCREEN; *pSendBuf++ = (int) (ctx->pScreen->myNum); if (client->swapped) { __glXSwapQueryContextReply(client, &reply, sendBuf); } else { WriteToClient(client, sz_xGLXQueryContextReply, &reply); WriteToClient(client, nReplyBytes, 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; dixLookupResourceByType((void **) &ctx, req->context, __glXContextRes, client, DixReadAccess); if (!ctx) { client->errorValue = req->context; return __glXBadContext; } nProps = 4; reply = (xGLXQueryContextInfoEXTReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = nProps << 1, .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, &reply); WriteToClient(client, nReplyBytes, 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 *pca = (CARD32 *) (be_req + 1); while (numAttribs-- > 0) { *pca++ = *attr++; /* token */ *pca++ = *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 */ dixLookupResourceByType((void **) &pGlxPbuffer, pbuffer, __glXPbufferRes, NullClient, DixUnknownAccess); 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 = 0; #ifdef PANORAMIX PanoramiXRes *pXinDraw = NULL; #endif if (drawId != None) { rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); if (rc == Success && 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; dixLookupResourceByType((void **) &pGlxPixmap, drawId, __glXPixmapRes, NullClient, DixUnknownAccess); if (pGlxPixmap) { pDraw = pGlxPixmap->pDraw; screen = pGlxPixmap->pScreen->myNum; be_drawable = pGlxPixmap->be_xids[screen]; } } if (!pDraw) { __glXWindow *pGlxWindow; dixLookupResourceByType((void **) &pGlxWindow, drawId, __glXWindowRes, NullClient, DixUnknownAccess); if (pGlxWindow) { pDraw = pGlxWindow->pDraw; screen = pGlxWindow->pScreen->myNum; be_drawable = 0; } } if (!pDraw) { __glXPbuffer *pGlxPbuffer; dixLookupResourceByType((void **) &pGlxPbuffer, drawId, __glXPbufferRes, NullClient, DixUnknownAccess); 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) { if (Success != dixLookupResourceByClass((void **) &pXinDraw, pDraw->id, XRC_DRAWABLE, client, DixReadAccess)) { 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, &reply); WriteToClient(client, attribs_size, attribs); } free(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; if (drawId != None) { rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess); if (rc == Success && pDraw->type == DRAWABLE_WINDOW) { be_drawable = 0; screen = pDraw->pScreen->myNum; } else { /* ** Drawable is not a Window , GLXWindow or a GLXPixmap. */ client->errorValue = drawId; return __glXBadDrawable; } if (!pDraw) { __GLXpixmap *pGlxPixmap; dixLookupResourceByType((void **) &pGlxPixmap, drawId, __glXPixmapRes, NullClient, DixUnknownAccess); if (pGlxPixmap) { pDraw = pGlxPixmap->pDraw; screen = pGlxPixmap->pScreen->myNum; be_drawable = pGlxPixmap->be_xids[screen]; } } if (!pDraw) { __glXWindow *pGlxWindow; dixLookupResourceByType((void **) &pGlxWindow, drawId, __glXWindowRes, NullClient, DixUnknownAccess); if (pGlxWindow) { pDraw = pGlxWindow->pDraw; screen = pGlxWindow->pScreen->myNum; be_drawable = 0; } } if (!pDraw) { __glXPbuffer *pGlxPbuffer; dixLookupResourceByType((void **) &pGlxPbuffer, drawId, __glXPbufferRes, NullClient, DixUnknownAccess); 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) { PanoramiXRes *pXinDraw; if (Success != dixLookupResourceByClass((void **) &pXinDraw, pDraw->id, XRC_DRAWABLE, client, DixReadAccess)) { 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; }