2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
38 #include "glxserver.h"
39 #include <GL/glxtokens.h>
41 #include "g_disptab.h"
42 #include <pixmapstr.h>
43 #include <windowstr.h>
46 #include "glapitable.h"
50 #include "indirect_dispatch.h"
51 #include "indirect_table.h"
52 #include "indirect_util.h"
55 validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err)
58 ** Check if screen exists.
60 if (screen >= screenInfo.numScreens) {
61 client->errorValue = screen;
65 *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
71 validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
72 __GLXconfig **config, int *err)
76 for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
77 if (m->fbconfigID == id) {
82 client->errorValue = id;
83 *err = __glXError(GLXBadFBConfig);
89 validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
90 __GLXconfig **config, int *err)
94 for (i = 0; i < pGlxScreen->numVisuals; i++)
95 if (pGlxScreen->visuals[i]->visualID == id) {
96 *config = pGlxScreen->visuals[i];
100 client->errorValue = id;
107 validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config,
108 DrawablePtr pDraw, int *err)
110 ScreenPtr pScreen = pDraw->pScreen;
111 VisualPtr pVisual = NULL;
115 vid = wVisual((WindowPtr)pDraw);
116 for (i = 0; i < pScreen->numVisuals; i++) {
117 if (pScreen->visuals[i].vid == vid) {
118 pVisual = &pScreen->visuals[i];
123 /* FIXME: What exactly should we check here... */
124 if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
125 !(config->drawableType & GLX_WINDOW_BIT)) {
126 client->errorValue = pDraw->id;
135 validGlxContext(ClientPtr client, XID id, int access_mode,
136 __GLXcontext **context, int *err)
138 *err = dixLookupResourceByType((pointer *) context, id,
139 __glXContextRes, client, access_mode);
140 if (*err != Success) {
141 client->errorValue = id;
142 if (*err == BadValue)
143 *err = __glXError(GLXBadContext);
151 validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
152 __GLXdrawable **drawable, int *err)
156 rc = dixLookupResourceByType((pointer *) drawable, id,
157 __glXDrawableRes, client, access_mode);
158 if (rc != Success && rc != BadValue) {
160 client->errorValue = id;
164 /* If the ID of the glx drawable we looked up doesn't match the id
165 * we looked for, it's because we looked it up under the X
166 * drawable ID (see DoCreateGLXDrawable). */
167 if (rc == BadValue ||
168 (*drawable)->drawId != id ||
169 (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
170 client->errorValue = id;
172 case GLX_DRAWABLE_WINDOW:
173 *err = __glXError(GLXBadWindow);
175 case GLX_DRAWABLE_PIXMAP:
176 *err = __glXError(GLXBadPixmap);
178 case GLX_DRAWABLE_PBUFFER:
179 *err = __glXError(GLXBadPbuffer);
181 case GLX_DRAWABLE_ANY:
182 *err = __glXError(GLXBadDrawable);
191 __glXContextDestroy(__GLXcontext *context)
193 __glXFlushContextCache();
196 static void __glXdirectContextDestroy(__GLXcontext *context)
198 __glXContextDestroy(context);
202 static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
204 __GLXcontext *shareContext)
206 __GLXcontext *context;
208 context = calloc(1, sizeof (__GLXcontext));
212 context->destroy = __glXdirectContextDestroy;
218 * Create a GL context with the given properties. This routine is used
219 * to implement \c glXCreateContext, \c glXCreateNewContext, and
220 * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way
221 * that GLXFBConfigs are implemented. Basically, the FBConfigID is the
222 * same as the VisualID.
226 DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
227 GLXContextID shareList, __GLXconfig *config,
228 __GLXscreen *pGlxScreen, GLboolean isDirect)
230 ClientPtr client = cl->client;
231 __GLXcontext *glxc, *shareglxc;
234 LEGAL_NEW_RESOURCE(gcId, client);
237 ** Find the display list space that we want to share.
239 ** NOTE: In a multithreaded X server, we would need to keep a reference
240 ** count for each display list so that if one client detroyed a list that
241 ** another client was using, the list would not really be freed until it
242 ** was no longer in use. Since this sample implementation has no support
243 ** for multithreaded servers, we don't do this.
245 if (shareList == None) {
248 if (!validGlxContext(client, shareList, DixReadAccess,
252 if (shareglxc->isDirect) {
254 ** NOTE: no support for sharing display lists between direct
255 ** contexts, even if they are in the same address space.
258 /* Disabling this code seems to allow shared display lists
259 * and texture objects to work. We'll leave it disabled for now.
261 client->errorValue = shareList;
266 ** Create an indirect context regardless of what the client asked
267 ** for; this way we can share display list space with shareList.
274 ** Allocate memory for the new context
277 glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc);
279 glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
285 ** Initially, setup the part of the context that could be used by
286 ** a GL core that needs windowing information (e.g., Mesa).
288 glxc->pGlxScreen = pGlxScreen;
289 glxc->config = config;
292 ** Register this context as a resource.
294 if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
295 (*glxc->destroy)(glxc);
296 client->errorValue = gcId;
301 ** Finally, now that everything is working, setup the rest of the
305 glxc->share_id = shareList;
306 glxc->idExists = GL_TRUE;
307 glxc->isCurrent = GL_FALSE;
308 glxc->isDirect = isDirect;
309 glxc->renderMode = GL_RENDER;
311 __glXAddToContextList(glxc);
316 int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc)
318 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
320 __GLXscreen *pGlxScreen;
323 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
325 if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
328 return DoCreateContext(cl, req->context, req->shareList,
329 config, pGlxScreen, req->isDirect);
332 int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
334 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
336 __GLXscreen *pGlxScreen;
339 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
341 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
344 return DoCreateContext(cl, req->context, req->shareList,
345 config, pGlxScreen, req->isDirect);
348 int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
350 xGLXCreateContextWithConfigSGIXReq *req =
351 (xGLXCreateContextWithConfigSGIXReq *) pc;
353 __GLXscreen *pGlxScreen;
356 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
358 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
361 return DoCreateContext(cl, req->context, req->shareList,
362 config, pGlxScreen, req->isDirect);
364 int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc)
366 xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
370 if (!validGlxContext(cl->client, req->context, DixDestroyAccess,
374 FreeResourceByType(req->context, __glXContextRes, FALSE);
378 /*****************************************************************************/
381 ** For each client, the server keeps a table of all the contexts that are
382 ** current for that client (each thread of a client may have its own current
383 ** context). These routines add, change, and lookup contexts in the table.
387 ** Add a current context, and return the tag that will be used to refer to it.
389 static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc)
392 int num = cl->numCurrentContexts;
393 __GLXcontext **table = cl->currentContexts;
395 if (!glxc) return -1;
398 ** Try to find an empty slot and use it.
400 for (i=0; i < num; i++) {
407 ** Didn't find a free slot, so we'll have to grow the table.
410 table = (__GLXcontext **) malloc(sizeof(__GLXcontext *));
412 table = (__GLXcontext **) realloc(table,
413 (num+1)*sizeof(__GLXcontext *));
416 cl->currentContexts = table;
417 cl->numCurrentContexts++;
422 ** Given a tag, change the current context for the corresponding entry.
424 static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
427 __GLXcontext **table = cl->currentContexts;
432 ** For this implementation we have chosen to simply use the index of the
433 ** context's entry in the table as the context tag. A tag must be greater
436 __GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
438 int num = cl->numCurrentContexts;
440 if (tag < 1 || tag > num) {
443 return cl->currentContexts[tag-1];
447 /*****************************************************************************/
449 static void StopUsingContext(__GLXcontext *glxc)
452 if (glxc == __glXLastContext) {
453 /* Tell server GL library */
454 __glXLastContext = 0;
456 glxc->isCurrent = GL_FALSE;
457 if (!glxc->idExists) {
458 __glXFreeContext(glxc);
463 static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
465 glxc->isCurrent = GL_TRUE;
466 __glXLastContext = glxc;
470 * This is a helper function to handle the legacy (pre GLX 1.3) cases
471 * where passing an X window to glXMakeCurrent is valid. Given a
472 * resource ID, look up the GLX drawable if available, otherwise, make
473 * sure it's an X window and create a GLX drawable one the fly.
475 static __GLXdrawable *
476 __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
480 __GLXdrawable *pGlxDraw;
483 if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
484 DixWriteAccess, &pGlxDraw, &rc)) {
485 if (glxc != NULL && pGlxDraw->config != glxc->config) {
486 client->errorValue = drawId;
494 /* No active context and an unknown drawable, bail. */
496 client->errorValue = drawId;
501 /* The drawId wasn't a GLX drawable. Make sure it's a window and
502 * create a GLXWindow for it. Check that the drawable screen
503 * matches the context screen and that the context fbconfig is
504 * compatible with the window visual. */
506 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
507 if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
508 client->errorValue = drawId;
509 *error = __glXError(GLXBadDrawable);
513 if (pDraw->pScreen != glxc->pGlxScreen->pScreen) {
514 client->errorValue = pDraw->pScreen->myNum;
519 if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
522 pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
525 drawId, glxc->config);
527 /* since we are creating the drawablePrivate, drawId should be new */
528 if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
529 pGlxDraw->destroy (pGlxDraw);
537 /*****************************************************************************/
539 ** Make an OpenGL context and drawable current.
543 DoMakeCurrent(__GLXclientState *cl,
544 GLXDrawable drawId, GLXDrawable readId,
545 GLXContextID contextId, GLXContextTag tag)
547 ClientPtr client = cl->client;
548 xGLXMakeCurrentReply reply;
549 __GLXcontext *glxc, *prevglxc;
550 __GLXdrawable *drawPriv = NULL;
551 __GLXdrawable *readPriv = NULL;
556 ** If one is None and the other isn't, it's a bad match.
559 mask = (drawId == None) ? (1 << 0) : 0;
560 mask |= (readId == None) ? (1 << 1) : 0;
561 mask |= (contextId == None) ? (1 << 2) : 0;
563 if ( (mask != 0x00) && (mask != 0x07) ) {
568 ** Lookup old context. If we have one, it must be in a usable state.
571 prevglxc = __glXLookupContextByTag(cl, tag);
574 ** Tag for previous context is invalid.
576 return __glXError(GLXBadContextTag);
578 if (prevglxc->renderMode != GL_RENDER) {
579 /* Oops. Not in render mode render. */
580 client->errorValue = prevglxc->id;
581 return __glXError(GLXBadContextState);
588 ** Lookup new context. It must not be current for someone else.
590 if (contextId != None) {
593 if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error))
595 if ((glxc != prevglxc) && glxc->isCurrent) {
596 /* Context is current to somebody else */
600 assert( drawId != None );
601 assert( readId != None );
603 drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
604 if (drawPriv == NULL)
607 readPriv = __glXGetDrawable(glxc, readId, client, &status);
608 if (readPriv == NULL)
612 /* Switching to no context. Ignore new drawable. */
621 ** Flush the previous context if needed.
623 if (__GLX_HAS_UNFLUSHED_CMDS(prevglxc)) {
624 if (__glXForceCurrent(cl, tag, (int *)&error)) {
625 CALL_Flush( GET_DISPATCH(), () );
626 __GLX_NOTE_FLUSHED_CMDS(prevglxc);
633 ** Make the previous context not current.
635 if (!(*prevglxc->loseCurrent)(prevglxc)) {
636 return __glXError(GLXBadContext);
638 __glXFlushContextCache();
639 if (!prevglxc->isDirect) {
640 prevglxc->drawPriv = NULL;
641 prevglxc->readPriv = NULL;
646 if ((glxc != 0) && !glxc->isDirect) {
648 glxc->drawPriv = drawPriv;
649 glxc->readPriv = readPriv;
651 /* make the context current */
652 if (!(*glxc->makeCurrent)(glxc)) {
653 glxc->drawPriv = NULL;
654 glxc->readPriv = NULL;
655 return __glXError(GLXBadContext);
658 glxc->isCurrent = GL_TRUE;
662 ChangeCurrentContext(cl, glxc, tag);
663 StopUsingContext(prevglxc);
665 tag = AddCurrentContext(cl, glxc);
669 StartUsingContext(cl, glxc);
670 reply.contextTag = tag;
672 reply.contextTag = 0;
676 reply.type = X_Reply;
677 reply.sequenceNumber = client->sequence;
679 if (client->swapped) {
680 __glXSwapMakeCurrentReply(client, &reply);
682 WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)&reply);
687 int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
689 xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
691 return DoMakeCurrent( cl, req->drawable, req->drawable,
692 req->context, req->oldContextTag );
695 int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
697 xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
699 return DoMakeCurrent( cl, req->drawable, req->readdrawable,
700 req->context, req->oldContextTag );
703 int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
705 xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
707 return DoMakeCurrent( cl, req->drawable, req->readable,
708 req->context, req->oldContextTag );
711 int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc)
713 ClientPtr client = cl->client;
714 xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
715 xGLXIsDirectReply reply;
719 if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err))
722 reply.isDirect = glxc->isDirect;
724 reply.type = X_Reply;
725 reply.sequenceNumber = client->sequence;
727 if (client->swapped) {
728 __glXSwapIsDirectReply(client, &reply);
730 WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
736 int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc)
738 ClientPtr client = cl->client;
739 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
740 xGLXQueryVersionReply reply;
743 major = req->majorVersion;
744 minor = req->minorVersion;
749 ** Server should take into consideration the version numbers sent by the
750 ** client if it wants to work with older clients; however, in this
751 ** implementation the server just returns its version number.
753 reply.majorVersion = glxMajorVersion;
754 reply.minorVersion = glxMinorVersion;
756 reply.type = X_Reply;
757 reply.sequenceNumber = client->sequence;
759 if (client->swapped) {
760 __glXSwapQueryVersionReply(client, &reply);
762 WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
767 int __glXDisp_WaitGL(__GLXclientState *cl, GLbyte *pc)
769 xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
770 GLXContextTag tag = req->contextTag;
771 __GLXcontext *glxc = NULL;
775 glxc = __glXLookupContextByTag(cl, tag);
777 return __glXError(GLXBadContextTag);
779 if (!__glXForceCurrent(cl, req->contextTag, &error))
782 CALL_Finish( GET_DISPATCH(), () );
785 if (glxc && glxc->drawPriv->waitGL)
786 (*glxc->drawPriv->waitGL)(glxc->drawPriv);
791 int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc)
793 xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
794 GLXContextTag tag = req->contextTag;
795 __GLXcontext *glxc = NULL;
799 glxc = __glXLookupContextByTag(cl, tag);
801 return __glXError(GLXBadContextTag);
803 if (!__glXForceCurrent(cl, req->contextTag, &error))
807 if (glxc && glxc->drawPriv->waitX)
808 (*glxc->drawPriv->waitX)(glxc->drawPriv);
813 int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc)
815 ClientPtr client = cl->client;
816 xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
817 GLXContextID source = req->source;
818 GLXContextID dest = req->dest;
819 GLXContextTag tag = req->contextTag;
820 unsigned long mask = req->mask;
821 __GLXcontext *src, *dst;
824 if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error))
826 if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error))
830 ** They must be in the same address space, and same screen.
831 ** NOTE: no support for direct rendering contexts here.
833 if (src->isDirect || dst->isDirect ||
834 (src->pGlxScreen != dst->pGlxScreen)) {
835 client->errorValue = source;
840 ** The destination context must not be current for any client.
842 if (dst->isCurrent) {
843 client->errorValue = dest;
848 __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
851 return __glXError(GLXBadContextTag);
855 ** This would be caused by a faulty implementation of the client
861 ** In this case, glXCopyContext is in both GL and X streams, in terms
864 if (__glXForceCurrent(cl, tag, &error)) {
866 ** Do whatever is needed to make sure that all preceding requests
867 ** in both streams are completed before the copy is executed.
869 CALL_Finish( GET_DISPATCH(), () );
870 __GLX_NOTE_FLUSHED_CMDS(tagcx);
876 ** Issue copy. The only reason for failure is a bad mask.
878 if (!(*dst->copy)(dst, src, mask)) {
879 client->errorValue = mask;
886 GLX_VIS_CONFIG_UNPAIRED = 18,
887 GLX_VIS_CONFIG_PAIRED = 20
891 GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED
894 int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
896 xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
897 ClientPtr client = cl->client;
898 xGLXGetVisualConfigsReply reply;
899 __GLXscreen *pGlxScreen;
901 CARD32 buf[GLX_VIS_CONFIG_TOTAL];
903 __GLX_DECLARE_SWAP_VARIABLES;
904 __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
906 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
909 reply.numVisuals = pGlxScreen->numVisuals;
910 reply.numProps = GLX_VIS_CONFIG_TOTAL;
911 reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2;
912 reply.type = X_Reply;
913 reply.sequenceNumber = client->sequence;
915 if (client->swapped) {
916 __GLX_SWAP_SHORT(&reply.sequenceNumber);
917 __GLX_SWAP_INT(&reply.length);
918 __GLX_SWAP_INT(&reply.numVisuals);
919 __GLX_SWAP_INT(&reply.numProps);
922 WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
924 for (i = 0; i < pGlxScreen->numVisuals; i++) {
925 modes = pGlxScreen->visuals[i];
928 buf[p++] = modes->visualID;
929 buf[p++] = glxConvertToXVisualType( modes->visualType );
930 buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE;
932 buf[p++] = modes->redBits;
933 buf[p++] = modes->greenBits;
934 buf[p++] = modes->blueBits;
935 buf[p++] = modes->alphaBits;
936 buf[p++] = modes->accumRedBits;
937 buf[p++] = modes->accumGreenBits;
938 buf[p++] = modes->accumBlueBits;
939 buf[p++] = modes->accumAlphaBits;
941 buf[p++] = modes->doubleBufferMode;
942 buf[p++] = modes->stereoMode;
944 buf[p++] = modes->rgbBits;
945 buf[p++] = modes->depthBits;
946 buf[p++] = modes->stencilBits;
947 buf[p++] = modes->numAuxBuffers;
948 buf[p++] = modes->level;
950 assert(p == GLX_VIS_CONFIG_UNPAIRED);
952 ** Add token/value pairs for extensions.
954 buf[p++] = GLX_VISUAL_CAVEAT_EXT;
955 buf[p++] = modes->visualRating;
956 buf[p++] = GLX_TRANSPARENT_TYPE;
957 buf[p++] = modes->transparentPixel;
958 buf[p++] = GLX_TRANSPARENT_RED_VALUE;
959 buf[p++] = modes->transparentRed;
960 buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
961 buf[p++] = modes->transparentGreen;
962 buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
963 buf[p++] = modes->transparentBlue;
964 buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
965 buf[p++] = modes->transparentAlpha;
966 buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
967 buf[p++] = modes->transparentIndex;
968 buf[p++] = GLX_SAMPLES_SGIS;
969 buf[p++] = modes->samples;
970 buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
971 buf[p++] = modes->sampleBuffers;
972 buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */
975 assert(p == GLX_VIS_CONFIG_TOTAL);
976 if (client->swapped) {
977 __GLX_SWAP_INT_ARRAY(buf, p);
979 WriteToClient(client, __GLX_SIZE_CARD32 * p, (char *)buf);
984 #define __GLX_TOTAL_FBCONFIG_ATTRIBS (36)
985 #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
987 * Send the set of GLXFBConfigs to the client. There is not currently
988 * and interface into the driver on the server-side to get GLXFBConfigs,
989 * so we "invent" some based on the \c __GLXvisualConfig structures that
990 * the driver does supply.
992 * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
993 * is the same, so this routine pulls double duty.
997 DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
999 ClientPtr client = cl->client;
1000 xGLXGetFBConfigsReply reply;
1001 __GLXscreen *pGlxScreen;
1002 CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
1005 __GLX_DECLARE_SWAP_VARIABLES;
1006 __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
1008 if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
1011 reply.numFBConfigs = pGlxScreen->numFBConfigs;
1012 reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS;
1013 reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs);
1014 reply.type = X_Reply;
1015 reply.sequenceNumber = client->sequence;
1017 if (client->swapped) {
1018 __GLX_SWAP_SHORT(&reply.sequenceNumber);
1019 __GLX_SWAP_INT(&reply.length);
1020 __GLX_SWAP_INT(&reply.numFBConfigs);
1021 __GLX_SWAP_INT(&reply.numAttribs);
1024 WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
1026 for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
1029 #define WRITE_PAIR(tag,value) \
1030 do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
1032 WRITE_PAIR( GLX_VISUAL_ID, modes->visualID );
1033 WRITE_PAIR( GLX_FBCONFIG_ID, modes->fbconfigID );
1034 WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE );
1036 WRITE_PAIR( GLX_RGBA,
1037 (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE );
1038 WRITE_PAIR( GLX_RENDER_TYPE, modes->renderType );
1039 WRITE_PAIR( GLX_DOUBLEBUFFER, modes->doubleBufferMode );
1040 WRITE_PAIR( GLX_STEREO, modes->stereoMode );
1042 WRITE_PAIR( GLX_BUFFER_SIZE, modes->rgbBits );
1043 WRITE_PAIR( GLX_LEVEL, modes->level );
1044 WRITE_PAIR( GLX_AUX_BUFFERS, modes->numAuxBuffers );
1045 WRITE_PAIR( GLX_RED_SIZE, modes->redBits );
1046 WRITE_PAIR( GLX_GREEN_SIZE, modes->greenBits );
1047 WRITE_PAIR( GLX_BLUE_SIZE, modes->blueBits );
1048 WRITE_PAIR( GLX_ALPHA_SIZE, modes->alphaBits );
1049 WRITE_PAIR( GLX_ACCUM_RED_SIZE, modes->accumRedBits );
1050 WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits );
1051 WRITE_PAIR( GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits );
1052 WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits );
1053 WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits );
1054 WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits );
1055 WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType );
1056 WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating );
1057 WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel );
1058 WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed );
1059 WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen );
1060 WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue );
1061 WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha );
1062 WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex );
1063 WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod );
1064 WRITE_PAIR( GLX_SAMPLES_SGIS, modes->samples );
1065 WRITE_PAIR( GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers );
1066 /* GLX_VISUAL_SELECT_GROUP_SGIX ? */
1067 WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType );
1068 WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb );
1069 WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba );
1070 WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture );
1071 WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets );
1073 if (client->swapped) {
1074 __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
1076 WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
1083 int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
1085 xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
1086 return DoGetFBConfigs(cl, req->screen);
1089 int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
1091 xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
1092 return DoGetFBConfigs(cl, req->screen);
1096 __glXDrawableInit(__GLXdrawable *drawable,
1097 __GLXscreen *screen, DrawablePtr pDraw, int type,
1098 XID drawId, __GLXconfig *config)
1100 drawable->pDraw = pDraw;
1101 drawable->type = type;
1102 drawable->drawId = drawId;
1103 drawable->config = config;
1104 drawable->eventMask = 0;
1110 __glXDrawableRelease(__GLXdrawable *drawable)
1115 DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen,
1116 __GLXconfig *config, DrawablePtr pDraw, XID drawableId,
1117 XID glxDrawableId, int type)
1119 __GLXdrawable *pGlxDraw;
1121 if (pGlxScreen->pScreen != pDraw->pScreen)
1124 pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
1126 glxDrawableId, config);
1127 if (pGlxDraw == NULL)
1130 if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) {
1131 pGlxDraw->destroy (pGlxDraw);
1135 /* Add the glx drawable under the XID of the underlying X drawable
1136 * too. That way we'll get a callback in DrawableGone and can
1137 * clean up properly when the drawable is destroyed. */
1138 if (drawableId != glxDrawableId &&
1139 !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
1140 pGlxDraw->destroy (pGlxDraw);
1148 DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
1149 XID drawableId, XID glxDrawableId)
1154 LEGAL_NEW_RESOURCE(glxDrawableId, client);
1156 err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
1157 if (err != Success) {
1158 client->errorValue = drawableId;
1161 if (pDraw->type != DRAWABLE_PIXMAP) {
1162 client->errorValue = drawableId;
1166 err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
1167 glxDrawableId, GLX_DRAWABLE_PIXMAP);
1173 determineTextureTarget(ClientPtr client, XID glxDrawableID,
1174 CARD32 *attribs, CARD32 numAttribs)
1179 __GLXdrawable *pGlxDraw;
1181 if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP,
1182 DixWriteAccess, &pGlxDraw, &err))
1183 /* We just added it in CreatePixmap, so we should never get here. */
1186 for (i = 0; i < numAttribs; i++) {
1187 if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
1188 switch (attribs[2 * i + 1]) {
1189 case GLX_TEXTURE_2D_EXT:
1190 target = GL_TEXTURE_2D;
1192 case GLX_TEXTURE_RECTANGLE_EXT:
1193 target = GL_TEXTURE_RECTANGLE_ARB;
1198 if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
1199 format = attribs[2 * i + 1];
1203 int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
1205 if (h & (h - 1) || w & (w - 1))
1206 target = GL_TEXTURE_RECTANGLE_ARB;
1208 target = GL_TEXTURE_2D;
1211 pGlxDraw->target = target;
1212 pGlxDraw->format = format;
1215 int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
1217 xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
1218 __GLXconfig *config;
1219 __GLXscreen *pGlxScreen;
1222 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1224 if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
1227 return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
1228 req->pixmap, req->glxpixmap);
1231 int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
1233 xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
1234 __GLXconfig *config;
1235 __GLXscreen *pGlxScreen;
1238 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1240 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
1243 err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
1244 req->pixmap, req->glxpixmap);
1248 determineTextureTarget(cl->client, req->glxpixmap,
1249 (CARD32*) (req + 1), req->numAttribs);
1254 int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
1256 xGLXCreateGLXPixmapWithConfigSGIXReq *req =
1257 (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
1258 __GLXconfig *config;
1259 __GLXscreen *pGlxScreen;
1262 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1264 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
1267 return DoCreateGLXPixmap(cl->client, pGlxScreen,
1268 config, req->pixmap, req->glxpixmap);
1272 static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
1274 __GLXdrawable *pGlxDraw;
1277 if (!validGlxDrawable(cl->client, glxdrawable, type,
1278 DixDestroyAccess, &pGlxDraw, &err))
1281 FreeResource(glxdrawable, FALSE);
1286 int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
1288 xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
1290 return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
1293 int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
1295 xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
1297 return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
1301 DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
1302 int width, int height, XID glxDrawableId)
1304 __GLXconfig *config;
1305 __GLXscreen *pGlxScreen;
1309 LEGAL_NEW_RESOURCE(glxDrawableId, client);
1311 if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
1313 if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
1316 __glXenterServer(GL_FALSE);
1317 pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
1318 width, height, config->rgbBits, 0);
1319 __glXleaveServer(GL_FALSE);
1321 /* Assign the pixmap the same id as the pbuffer and add it as a
1322 * resource so it and the DRI2 drawable will be reclaimed when the
1323 * pbuffer is destroyed. */
1324 pPixmap->drawable.id = glxDrawableId;
1325 if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap))
1328 return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
1329 glxDrawableId, glxDrawableId,
1330 GLX_DRAWABLE_PBUFFER);
1333 int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
1335 xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
1337 int width, height, i;
1339 attrs = (CARD32 *) (req + 1);
1343 for (i = 0; i < req->numAttribs; i++) {
1344 switch (attrs[i * 2]) {
1345 case GLX_PBUFFER_WIDTH:
1346 width = attrs[i * 2 + 1];
1348 case GLX_PBUFFER_HEIGHT:
1349 height = attrs[i * 2 + 1];
1351 case GLX_LARGEST_PBUFFER:
1352 case GLX_PRESERVED_CONTENTS:
1358 return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
1359 width, height, req->pbuffer);
1362 int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
1364 xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
1366 return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
1367 req->width, req->height, req->pbuffer);
1370 int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
1372 xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
1374 return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
1377 int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
1379 xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
1381 return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
1385 DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
1386 int numAttribs, CARD32 *attribs)
1388 __GLXdrawable *pGlxDraw;
1391 if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY,
1392 DixSetAttrAccess, &pGlxDraw, &err))
1395 for (i = 0; i < numAttribs; i++) {
1396 switch(attribs[i * 2]) {
1397 case GLX_EVENT_MASK:
1398 /* All we do is to record the event mask so we can send it
1399 * back when queried. We never actually clobber the
1400 * pbuffers, so we never need to send out the event. */
1401 pGlxDraw->eventMask = attribs[i * 2 + 1];
1409 int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
1411 xGLXChangeDrawableAttributesReq *req =
1412 (xGLXChangeDrawableAttributesReq *) pc;
1414 return DoChangeDrawableAttributes(cl->client, req->drawable,
1415 req->numAttribs, (CARD32 *) (req + 1));
1418 int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
1420 xGLXChangeDrawableAttributesSGIXReq *req =
1421 (xGLXChangeDrawableAttributesSGIXReq *)pc;
1423 return DoChangeDrawableAttributes(cl->client, req->drawable,
1424 req->numAttribs, (CARD32 *) (req + 1));
1427 int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
1429 xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
1430 __GLXconfig *config;
1431 __GLXscreen *pGlxScreen;
1432 ClientPtr client = cl->client;
1436 LEGAL_NEW_RESOURCE(req->glxwindow, client);
1438 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
1440 if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
1443 err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess);
1444 if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
1445 client->errorValue = req->window;
1449 if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
1452 return DoCreateGLXDrawable(client, pGlxScreen, config,
1454 req->glxwindow, GLX_DRAWABLE_WINDOW);
1457 int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
1459 xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
1461 return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
1465 /*****************************************************************************/
1468 ** NOTE: There is no portable implementation for swap buffers as of
1469 ** this time that is of value. Consequently, this code must be
1470 ** implemented by somebody other than SGI.
1472 int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
1474 ClientPtr client = cl->client;
1475 xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
1476 GLXContextTag tag = req->contextTag;
1477 XID drawId = req->drawable;
1478 __GLXcontext *glxc = NULL;
1479 __GLXdrawable *pGlxDraw;
1483 glxc = __glXLookupContextByTag(cl, tag);
1485 return __glXError(GLXBadContextTag);
1488 ** The calling thread is swapping its current drawable. In this case,
1489 ** glxSwapBuffers is in both GL and X streams, in terms of
1492 if (__glXForceCurrent(cl, tag, &error)) {
1494 ** Do whatever is needed to make sure that all preceding requests
1495 ** in both streams are completed before the swap is executed.
1497 CALL_Finish( GET_DISPATCH(), () );
1498 __GLX_NOTE_FLUSHED_CMDS(glxc);
1504 pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
1505 if (pGlxDraw == NULL)
1508 if (pGlxDraw->type == DRAWABLE_WINDOW &&
1509 (*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE)
1510 return __glXError(GLXBadDrawable);
1517 DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
1519 ClientPtr client = cl->client;
1521 xGLXQueryContextInfoEXTReply reply;
1523 int *sendBuf, *pSendBuf;
1527 if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err))
1531 reply.length = nProps << 1;
1532 reply.type = X_Reply;
1533 reply.sequenceNumber = client->sequence;
1536 nReplyBytes = reply.length << 2;
1537 sendBuf = (int *)malloc((size_t)nReplyBytes);
1538 if (sendBuf == NULL) {
1539 return __glXError(GLXBadContext); /* XXX: Is this correct? */
1542 *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
1543 *pSendBuf++ = (int)(ctx->share_id);
1544 *pSendBuf++ = GLX_VISUAL_ID_EXT;
1545 *pSendBuf++ = (int)(ctx->config->visualID);
1546 *pSendBuf++ = GLX_SCREEN_EXT;
1547 *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum);
1549 if (client->swapped) {
1550 __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
1552 WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
1553 WriteToClient(client, nReplyBytes, (char *)sendBuf);
1555 free((char *)sendBuf);
1560 int __glXDisp_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
1562 xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
1564 return DoQueryContext(cl, req->context);
1567 int __glXDisp_QueryContext(__GLXclientState *cl, GLbyte *pc)
1569 xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
1571 return DoQueryContext(cl, req->context);
1574 int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
1576 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1577 ClientPtr client = cl->client;
1578 __GLXcontext *context;
1579 __GLXdrawable *pGlxDraw;
1584 pc += __GLX_VENDPRIV_HDR_SIZE;
1586 drawId = *((CARD32 *) (pc));
1587 buffer = *((INT32 *) (pc + 4));
1589 if (buffer != GLX_FRONT_LEFT_EXT)
1590 return __glXError(GLXBadPixmap);
1592 context = __glXForceCurrent (cl, req->contextTag, &error);
1596 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
1597 DixReadAccess, &pGlxDraw, &error))
1600 if (!context->textureFromPixmap)
1601 return __glXError(GLXUnsupportedPrivateRequest);
1603 return context->textureFromPixmap->bindTexImage(context,
1608 int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
1610 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1611 ClientPtr client = cl->client;
1612 __GLXdrawable *pGlxDraw;
1613 __GLXcontext *context;
1618 pc += __GLX_VENDPRIV_HDR_SIZE;
1620 drawId = *((CARD32 *) (pc));
1621 buffer = *((INT32 *) (pc + 4));
1623 context = __glXForceCurrent (cl, req->contextTag, &error);
1627 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
1628 DixReadAccess, &pGlxDraw, &error))
1631 if (!context->textureFromPixmap)
1632 return __glXError(GLXUnsupportedPrivateRequest);
1634 return context->textureFromPixmap->releaseTexImage(context,
1639 int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
1641 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1642 GLXContextTag tag = req->contextTag;
1643 __GLXcontext *glxc = NULL;
1644 __GLXdrawable *pGlxDraw;
1645 ClientPtr client = cl->client;
1648 int x, y, width, height;
1653 pc += __GLX_VENDPRIV_HDR_SIZE;
1655 drawId = *((CARD32 *) (pc));
1656 x = *((INT32 *) (pc + 4));
1657 y = *((INT32 *) (pc + 8));
1658 width = *((INT32 *) (pc + 12));
1659 height = *((INT32 *) (pc + 16));
1662 glxc = __glXLookupContextByTag(cl, tag);
1664 return __glXError(GLXBadContextTag);
1667 ** The calling thread is swapping its current drawable. In this case,
1668 ** glxSwapBuffers is in both GL and X streams, in terms of
1671 if (__glXForceCurrent(cl, tag, &error)) {
1673 ** Do whatever is needed to make sure that all preceding requests
1674 ** in both streams are completed before the swap is executed.
1676 CALL_Finish( GET_DISPATCH(), () );
1677 __GLX_NOTE_FLUSHED_CMDS(glxc);
1683 pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
1687 if (pGlxDraw == NULL ||
1688 pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
1689 pGlxDraw->copySubBuffer == NULL)
1690 return __glXError(GLXBadDrawable);
1692 (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height);
1698 ** Get drawable attributes
1701 DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
1703 ClientPtr client = cl->client;
1704 xGLXGetDrawableAttributesReply reply;
1705 __GLXdrawable *pGlxDraw;
1706 CARD32 attributes[6];
1707 int numAttribs, error;
1709 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
1710 DixGetAttrAccess, &pGlxDraw, &error))
1714 reply.length = numAttribs << 1;
1715 reply.type = X_Reply;
1716 reply.sequenceNumber = client->sequence;
1717 reply.numAttribs = numAttribs;
1719 attributes[0] = GLX_TEXTURE_TARGET_EXT;
1720 attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
1721 GLX_TEXTURE_RECTANGLE_EXT;
1722 attributes[2] = GLX_Y_INVERTED_EXT;
1723 attributes[3] = GL_FALSE;
1724 attributes[4] = GLX_EVENT_MASK;
1725 attributes[5] = pGlxDraw->eventMask;
1727 if (client->swapped) {
1728 __glXSwapGetDrawableAttributesReply(client, &reply, attributes);
1730 WriteToClient(client, sz_xGLXGetDrawableAttributesReply,
1732 WriteToClient(client, reply.length * sizeof (CARD32),
1733 (char *)attributes);
1739 int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
1741 xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
1743 return DoGetDrawableAttributes(cl, req->drawable);
1746 int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
1748 xGLXGetDrawableAttributesSGIXReq *req =
1749 (xGLXGetDrawableAttributesSGIXReq *)pc;
1751 return DoGetDrawableAttributes(cl, req->drawable);
1754 /************************************************************************/
1757 ** Render and Renderlarge are not in the GLX API. They are used by the GLX
1758 ** client library to send batches of GL rendering commands.
1762 ** Execute all the drawing commands in a request.
1764 int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc)
1767 ClientPtr client= cl->client;
1768 int left, cmdlen, error;
1771 __GLXrenderHeader *hdr;
1773 __GLX_DECLARE_SWAP_VARIABLES;
1775 req = (xGLXRenderReq *) pc;
1776 if (client->swapped) {
1777 __GLX_SWAP_SHORT(&req->length);
1778 __GLX_SWAP_INT(&req->contextTag);
1781 glxc = __glXForceCurrent(cl, req->contextTag, &error);
1787 pc += sz_xGLXRenderReq;
1788 left = (req->length << 2) - sz_xGLXRenderReq;
1790 __GLXrenderSizeData entry;
1792 __GLXdispatchRenderProcPtr proc;
1796 ** Verify that the header length and the overall length agree.
1797 ** Also, each command must be word aligned.
1799 hdr = (__GLXrenderHeader *) pc;
1800 if (client->swapped) {
1801 __GLX_SWAP_SHORT(&hdr->length);
1802 __GLX_SWAP_SHORT(&hdr->opcode);
1804 cmdlen = hdr->length;
1805 opcode = hdr->opcode;
1808 ** Check for core opcodes and grab entry data.
1810 err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
1811 proc = (__GLXdispatchRenderProcPtr)
1812 __glXGetProtocolDecodeFunction(& Render_dispatch_info,
1813 opcode, client->swapped);
1815 if ((err < 0) || (proc == NULL)) {
1816 client->errorValue = commandsDone;
1817 return __glXError(GLXBadRenderRequest);
1820 if (entry.varsize) {
1821 /* variable size command */
1822 extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE,
1827 if (cmdlen != __GLX_PAD(entry.bytes + extra)) {
1831 /* constant size command */
1832 if (cmdlen != __GLX_PAD(entry.bytes)) {
1836 if (left < cmdlen) {
1841 ** Skip over the header and execute the command. We allow the
1842 ** caller to trash the command memory. This is useful especially
1843 ** for things that require double alignment - they can just shift
1844 ** the data towards lower memory (trashing the header) by 4 bytes
1845 ** and achieve the required alignment.
1847 (*proc)(pc + __GLX_RENDER_HDR_SIZE);
1852 __GLX_NOTE_UNFLUSHED_CMDS(glxc);
1858 ** Execute a large rendering request (one that spans multiple X requests).
1860 int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc)
1862 xGLXRenderLargeReq *req;
1863 ClientPtr client= cl->client;
1865 __GLXrenderLargeHeader *hdr;
1869 __GLX_DECLARE_SWAP_VARIABLES;
1871 req = (xGLXRenderLargeReq *) pc;
1872 if (client->swapped) {
1873 __GLX_SWAP_SHORT(&req->length);
1874 __GLX_SWAP_INT(&req->contextTag);
1875 __GLX_SWAP_INT(&req->dataBytes);
1876 __GLX_SWAP_SHORT(&req->requestNumber);
1877 __GLX_SWAP_SHORT(&req->requestTotal);
1880 glxc = __glXForceCurrent(cl, req->contextTag, &error);
1882 /* Reset in case this isn't 1st request. */
1883 __glXResetLargeCommandStatus(cl);
1886 dataBytes = req->dataBytes;
1889 ** Check the request length.
1891 if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) {
1892 client->errorValue = req->length;
1893 /* Reset in case this isn't 1st request. */
1894 __glXResetLargeCommandStatus(cl);
1897 pc += sz_xGLXRenderLargeReq;
1899 if (cl->largeCmdRequestsSoFar == 0) {
1900 __GLXrenderSizeData entry;
1906 ** This is the first request of a multi request command.
1907 ** Make enough space in the buffer, then copy the entire request.
1909 if (req->requestNumber != 1) {
1910 client->errorValue = req->requestNumber;
1911 return __glXError(GLXBadLargeRequest);
1914 hdr = (__GLXrenderLargeHeader *) pc;
1915 if (client->swapped) {
1916 __GLX_SWAP_INT(&hdr->length);
1917 __GLX_SWAP_INT(&hdr->opcode);
1919 cmdlen = hdr->length;
1920 opcode = hdr->opcode;
1923 ** Check for core opcodes and grab entry data.
1925 err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
1927 client->errorValue = opcode;
1928 return __glXError(GLXBadLargeRequest);
1931 if (entry.varsize) {
1933 ** If it's a variable-size command (a command whose length must
1934 ** be computed from its parameters), all the parameters needed
1935 ** will be in the 1st request, so it's okay to do this.
1937 extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE,
1942 /* large command's header is 4 bytes longer, so add 4 */
1943 if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) {
1947 /* constant size command */
1948 if (cmdlen != __GLX_PAD(entry.bytes + 4)) {
1953 ** Make enough space in the buffer, then copy the entire request.
1955 if (cl->largeCmdBufSize < cmdlen) {
1956 if (!cl->largeCmdBuf) {
1957 cl->largeCmdBuf = (GLbyte *) malloc(cmdlen);
1959 cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf, cmdlen);
1961 if (!cl->largeCmdBuf) {
1964 cl->largeCmdBufSize = cmdlen;
1966 memcpy(cl->largeCmdBuf, pc, dataBytes);
1968 cl->largeCmdBytesSoFar = dataBytes;
1969 cl->largeCmdBytesTotal = cmdlen;
1970 cl->largeCmdRequestsSoFar = 1;
1971 cl->largeCmdRequestsTotal = req->requestTotal;
1976 ** We are receiving subsequent (i.e. not the first) requests of a
1977 ** multi request command.
1981 ** Check the request number and the total request count.
1983 if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) {
1984 client->errorValue = req->requestNumber;
1985 __glXResetLargeCommandStatus(cl);
1986 return __glXError(GLXBadLargeRequest);
1988 if (req->requestTotal != cl->largeCmdRequestsTotal) {
1989 client->errorValue = req->requestTotal;
1990 __glXResetLargeCommandStatus(cl);
1991 return __glXError(GLXBadLargeRequest);
1995 ** Check that we didn't get too much data.
1997 if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) {
1998 client->errorValue = dataBytes;
1999 __glXResetLargeCommandStatus(cl);
2000 return __glXError(GLXBadLargeRequest);
2002 memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes);
2003 cl->largeCmdBytesSoFar += dataBytes;
2004 cl->largeCmdRequestsSoFar++;
2006 if (req->requestNumber == cl->largeCmdRequestsTotal) {
2007 __GLXdispatchRenderProcPtr proc;
2010 ** This is the last request; it must have enough bytes to complete
2013 /* NOTE: the two pad macros have been added below; they are needed
2014 ** because the client library pads the total byte count, but not
2015 ** the per-request byte counts. The Protocol Encoding says the
2016 ** total byte count should not be padded, so a proposal will be
2017 ** made to the ARB to relax the padding constraint on the total
2018 ** byte count, thus preserving backward compatibility. Meanwhile,
2019 ** the padding done below fixes a bug that did not allow
2020 ** large commands of odd sizes to be accepted by the server.
2022 if (__GLX_PAD(cl->largeCmdBytesSoFar) !=
2023 __GLX_PAD(cl->largeCmdBytesTotal)) {
2024 client->errorValue = dataBytes;
2025 __glXResetLargeCommandStatus(cl);
2026 return __glXError(GLXBadLargeRequest);
2028 hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf;
2030 ** The opcode and length field in the header had already been
2031 ** swapped when the first request was received.
2033 ** Use the opcode to index into the procedure table.
2035 opcode = hdr->opcode;
2037 proc = (__GLXdispatchRenderProcPtr)
2038 __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode,
2041 client->errorValue = opcode;
2042 return __glXError(GLXBadLargeRequest);
2046 ** Skip over the header and execute the command.
2048 (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
2049 __GLX_NOTE_UNFLUSHED_CMDS(glxc);
2052 ** Reset for the next RenderLarge series.
2054 __glXResetLargeCommandStatus(cl);
2057 ** This is neither the first nor the last request.
2064 extern RESTYPE __glXSwapBarrierRes;
2066 int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
2068 ClientPtr client = cl->client;
2069 xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *) pc;
2070 XID drawable = req->drawable;
2071 int barrier = req->barrier;
2074 __GLXscreen *pGlxScreen;
2076 rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixGetAttrAccess);
2077 pGlxScreen = glxGetScreen(pDraw->pScreen);
2078 if (rc == Success && (pDraw->type == DRAWABLE_WINDOW)) {
2079 screen = pDraw->pScreen->myNum;
2080 if (pGlxScreen->swapBarrierFuncs) {
2081 int ret = pGlxScreen->swapBarrierFuncs->bindSwapBarrierFunc(screen, drawable, barrier);
2082 if (ret == Success) {
2084 /* add source for cleanup when drawable is gone */
2085 AddResource(drawable, __glXSwapBarrierRes, (pointer)(intptr_t)screen);
2088 FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
2093 client->errorValue = drawable;
2094 return __glXError(GLXBadDrawable);
2098 int __glXDisp_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
2100 ClientPtr client = cl->client;
2101 xGLXQueryMaxSwapBarriersSGIXReq *req =
2102 (xGLXQueryMaxSwapBarriersSGIXReq *) pc;
2103 xGLXQueryMaxSwapBarriersSGIXReply reply;
2104 int screen = req->screen;
2105 __GLXscreen *pGlxScreen;
2107 pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
2108 if (pGlxScreen->swapBarrierFuncs)
2109 reply.max = pGlxScreen->swapBarrierFuncs->queryMaxSwapBarriersFunc(screen);
2115 reply.type = X_Reply;
2116 reply.sequenceNumber = client->sequence;
2118 if (client->swapped) {
2119 __GLX_DECLARE_SWAP_VARIABLES;
2120 __GLX_SWAP_SHORT(&reply.sequenceNumber);
2123 WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
2128 #define GLX_BAD_HYPERPIPE_SGIX 92
2130 int __glXDisp_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc)
2132 ClientPtr client = cl->client;
2133 xGLXQueryHyperpipeNetworkSGIXReq * req = (xGLXQueryHyperpipeNetworkSGIXReq *) pc;
2134 xGLXQueryHyperpipeNetworkSGIXReply reply;
2135 int screen = req->screen;
2142 __GLXscreen *pGlxScreen;
2144 pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
2145 if (pGlxScreen->hyperpipeFuncs) {
2147 (pGlxScreen->hyperpipeFuncs->queryHyperpipeNetworkFunc(screen, &npipes, &n));
2149 length = __GLX_PAD(n) >> 2;
2150 reply.type = X_Reply;
2151 reply.sequenceNumber = client->sequence;
2152 reply.length = length;
2154 reply.npipes = npipes;
2156 if (client->swapped) {
2157 __GLX_DECLARE_SWAP_VARIABLES;
2158 __GLX_SWAP_SHORT(&reply.sequenceNumber);
2159 __GLX_SWAP_INT(&reply.length);
2160 __GLX_SWAP_INT(&reply.n);
2161 __GLX_SWAP_INT(&reply.npipes);
2163 WriteToClient(client, sz_xGLXQueryHyperpipeNetworkSGIXReply,
2166 WriteToClient(client, length << 2, (char *)rdata);
2171 int __glXDisp_DestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc)
2173 ClientPtr client = cl->client;
2174 xGLXDestroyHyperpipeConfigSGIXReq * req =
2175 (xGLXDestroyHyperpipeConfigSGIXReq *) pc;
2176 xGLXDestroyHyperpipeConfigSGIXReply reply;
2177 int screen = req->screen;
2178 int success = GLX_BAD_HYPERPIPE_SGIX;
2180 __GLXscreen *pGlxScreen;
2184 pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
2185 if (pGlxScreen->hyperpipeFuncs) {
2186 success = pGlxScreen->hyperpipeFuncs->destroyHyperpipeConfigFunc(screen, hpId);
2189 reply.type = X_Reply;
2190 reply.sequenceNumber = client->sequence;
2191 reply.length = __GLX_PAD(0) >> 2;
2193 reply.success = success;
2196 if (client->swapped) {
2197 __GLX_DECLARE_SWAP_VARIABLES;
2198 __GLX_SWAP_SHORT(&reply.sequenceNumber);
2200 WriteToClient(client,
2201 sz_xGLXDestroyHyperpipeConfigSGIXReply,
2206 int __glXDisp_QueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
2208 ClientPtr client = cl->client;
2209 xGLXQueryHyperpipeConfigSGIXReq * req =
2210 (xGLXQueryHyperpipeConfigSGIXReq *) pc;
2211 xGLXQueryHyperpipeConfigSGIXReply reply;
2212 int screen = req->screen;
2218 __GLXscreen *pGlxScreen;
2222 pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
2223 if (pGlxScreen->hyperpipeFuncs) {
2224 rdata = pGlxScreen->hyperpipeFuncs->queryHyperpipeConfigFunc(screen, hpId,&npipes, &n);
2227 length = __GLX_PAD(n) >> 2;
2228 reply.type = X_Reply;
2229 reply.sequenceNumber = client->sequence;
2230 reply.length = length;
2232 reply.npipes = npipes;
2235 if (client->swapped) {
2236 __GLX_DECLARE_SWAP_VARIABLES;
2237 __GLX_SWAP_SHORT(&reply.sequenceNumber);
2238 __GLX_SWAP_INT(&reply.length);
2239 __GLX_SWAP_INT(&reply.n);
2240 __GLX_SWAP_INT(&reply.npipes);
2243 WriteToClient(client, sz_xGLXQueryHyperpipeConfigSGIXReply,
2246 WriteToClient(client, length << 2, (char *)rdata);
2251 int __glXDisp_HyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
2253 ClientPtr client = cl->client;
2254 xGLXHyperpipeConfigSGIXReq * req =
2255 (xGLXHyperpipeConfigSGIXReq *) pc;
2256 xGLXHyperpipeConfigSGIXReply reply;
2257 int screen = req->screen;
2260 int npipes=0, networkId;
2262 __GLXscreen *pGlxScreen;
2264 pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
2265 networkId = (int)req->networkId;
2266 npipes = (int)req->npipes;
2267 rdata = (void *)(req +1);
2269 if (pGlxScreen->hyperpipeFuncs) {
2270 pGlxScreen->hyperpipeFuncs->hyperpipeConfigFunc(screen,networkId,
2275 reply.type = X_Reply;
2276 reply.sequenceNumber = client->sequence;
2277 reply.length = __GLX_PAD(0) >> 2;
2279 reply.npipes = npipes;
2282 if (client->swapped) {
2283 __GLX_DECLARE_SWAP_VARIABLES;
2284 __GLX_SWAP_SHORT(&reply.sequenceNumber);
2285 __GLX_SWAP_INT(&reply.npipes);
2286 __GLX_SWAP_INT(&reply.hpId);
2289 WriteToClient(client, sz_xGLXHyperpipeConfigSGIXReply,
2296 /************************************************************************/
2299 ** No support is provided for the vendor-private requests other than
2300 ** allocating the entry points in the dispatch table.
2303 int __glXDisp_VendorPrivate(__GLXclientState *cl, GLbyte *pc)
2305 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
2306 GLint vendorcode = req->vendorCode;
2307 __GLXdispatchVendorPrivProcPtr proc;
2310 proc = (__GLXdispatchVendorPrivProcPtr)
2311 __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
2314 (*proc)(cl, (GLbyte*)req);
2318 cl->client->errorValue = req->vendorCode;
2319 return __glXError(GLXUnsupportedPrivateRequest);
2322 int __glXDisp_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
2324 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
2325 GLint vendorcode = req->vendorCode;
2326 __GLXdispatchVendorPrivProcPtr proc;
2329 proc = (__GLXdispatchVendorPrivProcPtr)
2330 __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
2333 return (*proc)(cl, (GLbyte*)req);
2336 cl->client->errorValue = vendorcode;
2337 return __glXError(GLXUnsupportedPrivateRequest);
2340 int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
2342 ClientPtr client = cl->client;
2343 xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
2344 xGLXQueryExtensionsStringReply reply;
2345 __GLXscreen *pGlxScreen;
2350 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
2353 n = strlen(pGlxScreen->GLXextensions) + 1;
2354 length = __GLX_PAD(n) >> 2;
2355 reply.type = X_Reply;
2356 reply.sequenceNumber = client->sequence;
2357 reply.length = length;
2360 /* Allocate buffer to make sure it's a multiple of 4 bytes big.*/
2361 buf = (char *) malloc(length << 2);
2364 memcpy(buf, pGlxScreen->GLXextensions, n);
2366 if (client->swapped) {
2367 glxSwapQueryExtensionsStringReply(client, &reply, buf);
2369 WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
2370 WriteToClient(client, (int)(length << 2), (char *)buf);
2377 int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
2379 ClientPtr client = cl->client;
2380 xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
2381 xGLXQueryServerStringReply reply;
2385 __GLXscreen *pGlxScreen;
2389 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
2394 ptr = pGlxScreen->GLXvendor;
2397 /* Return to the server version rather than the screen version
2398 * to prevent confusion when they do not match.
2400 snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion);
2403 case GLX_EXTENSIONS:
2404 ptr = pGlxScreen->GLXextensions;
2410 n = strlen(ptr) + 1;
2411 length = __GLX_PAD(n) >> 2;
2412 reply.type = X_Reply;
2413 reply.sequenceNumber = client->sequence;
2414 reply.length = length;
2417 buf = (char *) malloc(length << 2);
2421 memcpy(buf, ptr, n);
2423 if (client->swapped) {
2424 glxSwapQueryServerStringReply(client, &reply, buf);
2426 WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
2427 WriteToClient(client, (int)(length << 2), buf);
2434 int __glXDisp_ClientInfo(__GLXclientState *cl, GLbyte *pc)
2436 xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
2439 cl->GLClientmajorVersion = req->major;
2440 cl->GLClientminorVersion = req->minor;
2441 free(cl->GLClientextensions);
2442 buf = (const char *)(req+1);
2443 cl->GLClientextensions = strdup(buf);