xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

glxcmds.c (77752B)


      1 /*
      2  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
      3  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
      4  *
      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:
     11  *
     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.
     16  *
     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
     23  * SOFTWARE.
     24  *
     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.
     29  */
     30 
     31 #ifdef HAVE_DIX_CONFIG_H
     32 #include <dix-config.h>
     33 #endif
     34 
     35 #include <string.h>
     36 #include <assert.h>
     37 
     38 #include "glxserver.h"
     39 #include <GL/glxtokens.h>
     40 #include <X11/extensions/presenttokens.h>
     41 #include <unpack.h>
     42 #include <pixmapstr.h>
     43 #include <windowstr.h>
     44 #include "glxutil.h"
     45 #include "glxext.h"
     46 #include "indirect_dispatch.h"
     47 #include "indirect_table.h"
     48 #include "indirect_util.h"
     49 #include "protocol-versions.h"
     50 #include "glxvndabi.h"
     51 
     52 static char GLXServerVendorName[] = "SGI";
     53 
     54 _X_HIDDEN int
     55 validGlxScreen(ClientPtr client, int screen, __GLXscreen ** pGlxScreen,
     56                int *err)
     57 {
     58     /*
     59      ** Check if screen exists.
     60      */
     61     if (screen < 0 || screen >= screenInfo.numScreens) {
     62         client->errorValue = screen;
     63         *err = BadValue;
     64         return FALSE;
     65     }
     66     *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
     67 
     68     return TRUE;
     69 }
     70 
     71 _X_HIDDEN int
     72 validGlxFBConfig(ClientPtr client, __GLXscreen * pGlxScreen, XID id,
     73                  __GLXconfig ** config, int *err)
     74 {
     75     __GLXconfig *m;
     76 
     77     for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
     78         if (m->fbconfigID == id) {
     79             *config = m;
     80             return TRUE;
     81         }
     82 
     83     client->errorValue = id;
     84     *err = __glXError(GLXBadFBConfig);
     85 
     86     return FALSE;
     87 }
     88 
     89 static int
     90 validGlxVisual(ClientPtr client, __GLXscreen * pGlxScreen, XID id,
     91                __GLXconfig ** config, int *err)
     92 {
     93     int i;
     94 
     95     for (i = 0; i < pGlxScreen->numVisuals; i++)
     96         if (pGlxScreen->visuals[i]->visualID == id) {
     97             *config = pGlxScreen->visuals[i];
     98             return TRUE;
     99         }
    100 
    101     client->errorValue = id;
    102     *err = BadValue;
    103 
    104     return FALSE;
    105 }
    106 
    107 static int
    108 validGlxFBConfigForWindow(ClientPtr client, __GLXconfig * config,
    109                           DrawablePtr pDraw, int *err)
    110 {
    111     ScreenPtr pScreen = pDraw->pScreen;
    112     VisualPtr pVisual = NULL;
    113     XID vid;
    114     int i;
    115 
    116     vid = wVisual((WindowPtr) pDraw);
    117     for (i = 0; i < pScreen->numVisuals; i++) {
    118         if (pScreen->visuals[i].vid == vid) {
    119             pVisual = &pScreen->visuals[i];
    120             break;
    121         }
    122     }
    123 
    124     /* FIXME: What exactly should we check here... */
    125     if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
    126         !(config->drawableType & GLX_WINDOW_BIT)) {
    127         client->errorValue = pDraw->id;
    128         *err = BadMatch;
    129         return FALSE;
    130     }
    131 
    132     return TRUE;
    133 }
    134 
    135 _X_HIDDEN int
    136 validGlxContext(ClientPtr client, XID id, int access_mode,
    137                 __GLXcontext ** context, int *err)
    138 {
    139     /* no ghost contexts */
    140     if (id & SERVER_BIT) {
    141         *err = __glXError(GLXBadContext);
    142         return FALSE;
    143     }
    144 
    145     *err = dixLookupResourceByType((void **) context, id,
    146                                    __glXContextRes, client, access_mode);
    147     if (*err != Success || (*context)->idExists == GL_FALSE) {
    148         client->errorValue = id;
    149         if (*err == BadValue || *err == Success)
    150             *err = __glXError(GLXBadContext);
    151         return FALSE;
    152     }
    153 
    154     return TRUE;
    155 }
    156 
    157 int
    158 validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
    159                  __GLXdrawable ** drawable, int *err)
    160 {
    161     int rc;
    162 
    163     rc = dixLookupResourceByType((void **) drawable, id,
    164                                  __glXDrawableRes, client, access_mode);
    165     if (rc != Success && rc != BadValue) {
    166         *err = rc;
    167         client->errorValue = id;
    168         return FALSE;
    169     }
    170 
    171     /* If the ID of the glx drawable we looked up doesn't match the id
    172      * we looked for, it's because we looked it up under the X
    173      * drawable ID (see DoCreateGLXDrawable). */
    174     if (rc == BadValue ||
    175         (*drawable)->drawId != id ||
    176         (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
    177         client->errorValue = id;
    178         switch (type) {
    179         case GLX_DRAWABLE_WINDOW:
    180             *err = __glXError(GLXBadWindow);
    181             return FALSE;
    182         case GLX_DRAWABLE_PIXMAP:
    183             *err = __glXError(GLXBadPixmap);
    184             return FALSE;
    185         case GLX_DRAWABLE_PBUFFER:
    186             *err = __glXError(GLXBadPbuffer);
    187             return FALSE;
    188         case GLX_DRAWABLE_ANY:
    189             *err = __glXError(GLXBadDrawable);
    190             return FALSE;
    191         }
    192     }
    193 
    194     return TRUE;
    195 }
    196 
    197 void
    198 __glXContextDestroy(__GLXcontext * context)
    199 {
    200     lastGLContext = NULL;
    201 }
    202 
    203 static void
    204 __glXdirectContextDestroy(__GLXcontext * context)
    205 {
    206     __glXContextDestroy(context);
    207     free(context);
    208 }
    209 
    210 static int
    211 __glXdirectContextLoseCurrent(__GLXcontext * context)
    212 {
    213     return GL_TRUE;
    214 }
    215 
    216 _X_HIDDEN __GLXcontext *
    217 __glXdirectContextCreate(__GLXscreen * screen,
    218                          __GLXconfig * modes, __GLXcontext * shareContext)
    219 {
    220     __GLXcontext *context;
    221 
    222     context = calloc(1, sizeof(__GLXcontext));
    223     if (context == NULL)
    224         return NULL;
    225 
    226     context->config = modes;
    227     context->destroy = __glXdirectContextDestroy;
    228     context->loseCurrent = __glXdirectContextLoseCurrent;
    229 
    230     return context;
    231 }
    232 
    233 /**
    234  * Create a GL context with the given properties.  This routine is used
    235  * to implement \c glXCreateContext, \c glXCreateNewContext, and
    236  * \c glXCreateContextWithConfigSGIX.  This works because of the hack way
    237  * that GLXFBConfigs are implemented.  Basically, the FBConfigID is the
    238  * same as the VisualID.
    239  */
    240 
    241 static int
    242 DoCreateContext(__GLXclientState * cl, GLXContextID gcId,
    243                 GLXContextID shareList, __GLXconfig * config,
    244                 __GLXscreen * pGlxScreen, GLboolean isDirect,
    245                 int renderType)
    246 {
    247     ClientPtr client = cl->client;
    248     __GLXcontext *glxc, *shareglxc;
    249     int err;
    250 
    251     /*
    252      ** Find the display list space that we want to share.
    253      **
    254      ** NOTE: In a multithreaded X server, we would need to keep a reference
    255      ** count for each display list so that if one client destroyed a list that
    256      ** another client was using, the list would not really be freed until it
    257      ** was no longer in use.  Since this sample implementation has no support
    258      ** for multithreaded servers, we don't do this.
    259      */
    260     if (shareList == None) {
    261         shareglxc = 0;
    262     }
    263     else {
    264         if (!validGlxContext(client, shareList, DixReadAccess,
    265                              &shareglxc, &err))
    266             return err;
    267 
    268         /* Page 26 (page 32 of the PDF) of the GLX 1.4 spec says:
    269          *
    270          *     "The server context state for all sharing contexts must exist
    271          *     in a single address space or a BadMatch error is generated."
    272          *
    273          * If the share context is indirect, force the new context to also be
    274          * indirect.  If the shard context is direct but the new context
    275          * cannot be direct, generate BadMatch.
    276          */
    277         if (shareglxc->isDirect && !isDirect) {
    278             client->errorValue = shareList;
    279             return BadMatch;
    280         }
    281         else if (!shareglxc->isDirect) {
    282             /*
    283              ** Create an indirect context regardless of what the client asked
    284              ** for; this way we can share display list space with shareList.
    285              */
    286             isDirect = GL_FALSE;
    287         }
    288 
    289         /* Core GLX doesn't explicitly require this, but GLX_ARB_create_context
    290          * does (see glx/createcontext.c), and it's assumed by our
    291          * implementation anyway, so let's be consistent about it.
    292          */
    293         if (shareglxc->pGlxScreen != pGlxScreen) {
    294             client->errorValue = shareglxc->pGlxScreen->pScreen->myNum;
    295             return BadMatch;
    296         }
    297     }
    298 
    299     /*
    300      ** Allocate memory for the new context
    301      */
    302     if (!isDirect) {
    303         /* Only allow creating indirect GLX contexts if allowed by
    304          * server command line.  Indirect GLX is of limited use (since
    305          * it's only GL 1.4), it's slower than direct contexts, and
    306          * it's a massive attack surface for buffer overflow type
    307          * errors.
    308          */
    309         if (!enableIndirectGLX) {
    310             client->errorValue = isDirect;
    311             return BadValue;
    312         }
    313 
    314         /* Without any attributes, the only error that the driver should be
    315          * able to generate is BadAlloc.  As result, just drop the error
    316          * returned from the driver on the floor.
    317          */
    318         glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc,
    319                                          0, NULL, &err);
    320     }
    321     else
    322         glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
    323     if (!glxc) {
    324         return BadAlloc;
    325     }
    326 
    327     /* Initialize the GLXcontext structure.
    328      */
    329     glxc->pGlxScreen = pGlxScreen;
    330     glxc->config = config;
    331     glxc->id = gcId;
    332     glxc->share_id = shareList;
    333     glxc->idExists = GL_TRUE;
    334     glxc->isDirect = isDirect;
    335     glxc->renderMode = GL_RENDER;
    336     glxc->renderType = renderType;
    337 
    338     /* The GLX_ARB_create_context_robustness spec says:
    339      *
    340      *     "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
    341      *     is GLX_NO_RESET_NOTIFICATION_ARB."
    342      *
    343      * Without using glXCreateContextAttribsARB, there is no way to specify a
    344      * non-default reset notification strategy.
    345      */
    346     glxc->resetNotificationStrategy = GLX_NO_RESET_NOTIFICATION_ARB;
    347 
    348 #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
    349     /* The GLX_ARB_context_flush_control spec says:
    350      *
    351      *     "The default value [for GLX_CONTEXT_RELEASE_BEHAVIOR] is
    352      *     CONTEXT_RELEASE_BEHAVIOR_FLUSH, and may in some cases be changed
    353      *     using platform-specific context creation extensions."
    354      *
    355      * Without using glXCreateContextAttribsARB, there is no way to specify a
    356      * non-default release behavior.
    357      */
    358     glxc->releaseBehavior = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB;
    359 #endif
    360 
    361     /* Add the new context to the various global tables of GLX contexts.
    362      */
    363     if (!__glXAddContext(glxc)) {
    364         (*glxc->destroy) (glxc);
    365         client->errorValue = gcId;
    366         return BadAlloc;
    367     }
    368 
    369     return Success;
    370 }
    371 
    372 int
    373 __glXDisp_CreateContext(__GLXclientState * cl, GLbyte * pc)
    374 {
    375     xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
    376     __GLXconfig *config;
    377     __GLXscreen *pGlxScreen;
    378     int err;
    379 
    380     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
    381         return err;
    382     if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
    383         return err;
    384 
    385     return DoCreateContext(cl, req->context, req->shareList,
    386                            config, pGlxScreen, req->isDirect,
    387                            GLX_RGBA_TYPE);
    388 }
    389 
    390 int
    391 __glXDisp_CreateNewContext(__GLXclientState * cl, GLbyte * pc)
    392 {
    393     xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
    394     __GLXconfig *config;
    395     __GLXscreen *pGlxScreen;
    396     int err;
    397 
    398     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
    399         return err;
    400     if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
    401         return err;
    402 
    403     return DoCreateContext(cl, req->context, req->shareList,
    404                            config, pGlxScreen, req->isDirect,
    405                            req->renderType);
    406 }
    407 
    408 int
    409 __glXDisp_CreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc)
    410 {
    411     ClientPtr client = cl->client;
    412     xGLXCreateContextWithConfigSGIXReq *req =
    413         (xGLXCreateContextWithConfigSGIXReq *) pc;
    414     __GLXconfig *config;
    415     __GLXscreen *pGlxScreen;
    416     int err;
    417 
    418     REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq);
    419 
    420     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
    421         return err;
    422     if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
    423         return err;
    424 
    425     return DoCreateContext(cl, req->context, req->shareList,
    426                            config, pGlxScreen, req->isDirect,
    427                            req->renderType);
    428 }
    429 
    430 int
    431 __glXDisp_DestroyContext(__GLXclientState * cl, GLbyte * pc)
    432 {
    433     xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
    434     __GLXcontext *glxc;
    435     int err;
    436 
    437     if (!validGlxContext(cl->client, req->context, DixDestroyAccess,
    438                          &glxc, &err))
    439         return err;
    440 
    441     glxc->idExists = GL_FALSE;
    442     if (glxc->currentClient) {
    443         XID ghost = FakeClientID(glxc->currentClient->index);
    444 
    445         if (!AddResource(ghost, __glXContextRes, glxc))
    446             return BadAlloc;
    447         ChangeResourceValue(glxc->id, __glXContextRes, NULL);
    448         glxc->id = ghost;
    449     }
    450 
    451     FreeResourceByType(req->context, __glXContextRes, FALSE);
    452 
    453     return Success;
    454 }
    455 
    456 __GLXcontext *
    457 __glXLookupContextByTag(__GLXclientState * cl, GLXContextTag tag)
    458 {
    459     return glxServer.getContextTagPrivate(cl->client, tag);
    460 }
    461 
    462 static __GLXconfig *
    463 inferConfigForWindow(__GLXscreen *pGlxScreen, WindowPtr pWin)
    464 {
    465     int i, vid = wVisual(pWin);
    466 
    467     for (i = 0; i < pGlxScreen->numVisuals; i++)
    468         if (pGlxScreen->visuals[i]->visualID == vid)
    469             return pGlxScreen->visuals[i];
    470 
    471     return NULL;
    472 }
    473 
    474 /**
    475  * This is a helper function to handle the legacy (pre GLX 1.3) cases
    476  * where passing an X window to glXMakeCurrent is valid.  Given a
    477  * resource ID, look up the GLX drawable if available, otherwise, make
    478  * sure it's an X window and create a GLX drawable one the fly.
    479  */
    480 static __GLXdrawable *
    481 __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
    482                  int *error)
    483 {
    484     DrawablePtr pDraw;
    485     __GLXdrawable *pGlxDraw;
    486     __GLXconfig *config;
    487     __GLXscreen *pGlxScreen;
    488     int rc;
    489 
    490     rc = dixLookupResourceByType((void **)&pGlxDraw, drawId,
    491                                  __glXDrawableRes, client, DixWriteAccess);
    492     if (rc == Success &&
    493         /* If pGlxDraw->drawId == drawId, drawId is a valid GLX drawable.
    494          * Otherwise, if pGlxDraw->type == GLX_DRAWABLE_WINDOW, drawId is
    495          * an X window, but the client has already created a GLXWindow
    496          * associated with it, so we don't want to create another one. */
    497         (pGlxDraw->drawId == drawId ||
    498          pGlxDraw->type == GLX_DRAWABLE_WINDOW)) {
    499         if (glxc != NULL &&
    500             glxc->config != NULL &&
    501             glxc->config != pGlxDraw->config) {
    502             client->errorValue = drawId;
    503             *error = BadMatch;
    504             return NULL;
    505         }
    506 
    507         return pGlxDraw;
    508     }
    509 
    510     /* No active context and an unknown drawable, bail. */
    511     if (glxc == NULL) {
    512         client->errorValue = drawId;
    513         *error = BadMatch;
    514         return NULL;
    515     }
    516 
    517     /* The drawId wasn't a GLX drawable.  Make sure it's a window and
    518      * create a GLXWindow for it.  Check that the drawable screen
    519      * matches the context screen and that the context fbconfig is
    520      * compatible with the window visual. */
    521 
    522     rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
    523     if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
    524         client->errorValue = drawId;
    525         *error = __glXError(GLXBadDrawable);
    526         return NULL;
    527     }
    528 
    529     pGlxScreen = glxc->pGlxScreen;
    530     if (pDraw->pScreen != pGlxScreen->pScreen) {
    531         client->errorValue = pDraw->pScreen->myNum;
    532         *error = BadMatch;
    533         return NULL;
    534     }
    535 
    536     config = glxc->config;
    537     if (!config)
    538         config = inferConfigForWindow(pGlxScreen, (WindowPtr)pDraw);
    539     if (!config) {
    540         /*
    541          * If we get here, we've tried to bind a no-config context to a
    542          * window without a corresponding fbconfig, presumably because
    543          * we don't support GL on it (PseudoColor perhaps). From GLX Section
    544          * 3.3.7 "Rendering Contexts":
    545          *
    546          * "If draw or read are not compatible with ctx a BadMatch error
    547          * is generated."
    548          */
    549         *error = BadMatch;
    550         return NULL;
    551     }
    552 
    553     if (!validGlxFBConfigForWindow(client, config, pDraw, error))
    554         return NULL;
    555 
    556     pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawId,
    557                                           GLX_DRAWABLE_WINDOW, drawId, config);
    558     if (!pGlxDraw) {
    559 	*error = BadAlloc;
    560 	return NULL;
    561     }
    562 
    563     /* since we are creating the drawablePrivate, drawId should be new */
    564     if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
    565         *error = BadAlloc;
    566         return NULL;
    567     }
    568 
    569     return pGlxDraw;
    570 }
    571 
    572 /*****************************************************************************/
    573 /*
    574 ** Make an OpenGL context and drawable current.
    575 */
    576 
    577 int
    578 xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId,
    579                    XID contextId, GLXContextTag newContextTag)
    580 {
    581     __GLXclientState *cl = glxGetClient(client);
    582     __GLXcontext *glxc = NULL, *prevglxc = NULL;
    583     __GLXdrawable *drawPriv = NULL;
    584     __GLXdrawable *readPriv = NULL;
    585     int error;
    586 
    587     /* Drawables but no context makes no sense */
    588     if (!contextId && (drawId || readId))
    589         return BadMatch;
    590 
    591     /* If either drawable is null, the other must be too */
    592     if ((drawId == None) != (readId == None))
    593         return BadMatch;
    594 
    595     /* Look up old context. If we have one, it must be in a usable state. */
    596     if (tag != 0) {
    597         prevglxc = glxServer.getContextTagPrivate(client, tag);
    598 
    599         if (prevglxc && prevglxc->renderMode != GL_RENDER) {
    600             /* Oops.  Not in render mode render. */
    601             client->errorValue = prevglxc->id;
    602             return __glXError(GLXBadContextState);
    603         }
    604     }
    605 
    606     /* Look up new context. It must not be current for someone else. */
    607     if (contextId != None) {
    608         int status;
    609 
    610         if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error))
    611             return error;
    612 
    613         if ((glxc != prevglxc) && glxc->currentClient)
    614             return BadAccess;
    615 
    616         if (drawId) {
    617             drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
    618             if (drawPriv == NULL)
    619                 return status;
    620         }
    621 
    622         if (readId) {
    623             readPriv = __glXGetDrawable(glxc, readId, client, &status);
    624             if (readPriv == NULL)
    625                 return status;
    626         }
    627     }
    628 
    629     if (prevglxc) {
    630         /* Flush the previous context if needed. */
    631         Bool need_flush = !prevglxc->isDirect;
    632 #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
    633         if (prevglxc->releaseBehavior == GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB)
    634             need_flush = GL_FALSE;
    635 #endif
    636         if (need_flush) {
    637             if (!__glXForceCurrent(cl, tag, (int *) &error))
    638                 return error;
    639             glFlush();
    640         }
    641 
    642         /* Make the previous context not current. */
    643         if (!(*prevglxc->loseCurrent) (prevglxc))
    644             return __glXError(GLXBadContext);
    645 
    646         lastGLContext = NULL;
    647         if (!prevglxc->isDirect) {
    648             prevglxc->drawPriv = NULL;
    649             prevglxc->readPriv = NULL;
    650         }
    651     }
    652 
    653     if (glxc && !glxc->isDirect) {
    654         glxc->drawPriv = drawPriv;
    655         glxc->readPriv = readPriv;
    656 
    657         /* make the context current */
    658         lastGLContext = glxc;
    659         if (!(*glxc->makeCurrent) (glxc)) {
    660             lastGLContext = NULL;
    661             glxc->drawPriv = NULL;
    662             glxc->readPriv = NULL;
    663             return __glXError(GLXBadContext);
    664         }
    665     }
    666 
    667     glxServer.setContextTagPrivate(client, newContextTag, glxc);
    668     if (glxc)
    669         glxc->currentClient = client;
    670 
    671     if (prevglxc) {
    672         prevglxc->currentClient = NULL;
    673         if (!prevglxc->idExists) {
    674             FreeResourceByType(prevglxc->id, __glXContextRes, FALSE);
    675         }
    676     }
    677 
    678     return Success;
    679 }
    680 
    681 int
    682 __glXDisp_MakeCurrent(__GLXclientState * cl, GLbyte * pc)
    683 {
    684     return BadImplementation;
    685 }
    686 
    687 int
    688 __glXDisp_MakeContextCurrent(__GLXclientState * cl, GLbyte * pc)
    689 {
    690     return BadImplementation;
    691 }
    692 
    693 int
    694 __glXDisp_MakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc)
    695 {
    696     return BadImplementation;
    697 }
    698 
    699 int
    700 __glXDisp_IsDirect(__GLXclientState * cl, GLbyte * pc)
    701 {
    702     ClientPtr client = cl->client;
    703     xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
    704     xGLXIsDirectReply reply;
    705     __GLXcontext *glxc;
    706     int err;
    707 
    708     if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err))
    709         return err;
    710 
    711     reply = (xGLXIsDirectReply) {
    712         .type = X_Reply,
    713         .sequenceNumber = client->sequence,
    714         .length = 0,
    715         .isDirect = glxc->isDirect
    716     };
    717 
    718     if (client->swapped) {
    719         __GLX_DECLARE_SWAP_VARIABLES;
    720         __GLX_SWAP_SHORT(&reply.sequenceNumber);
    721         __GLX_SWAP_INT(&reply.length);
    722     }
    723     WriteToClient(client, sz_xGLXIsDirectReply, &reply);
    724 
    725     return Success;
    726 }
    727 
    728 int
    729 __glXDisp_QueryVersion(__GLXclientState * cl, GLbyte * pc)
    730 {
    731     ClientPtr client = cl->client;
    732     xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
    733     xGLXQueryVersionReply reply;
    734     GLuint major, minor;
    735 
    736     REQUEST_SIZE_MATCH(xGLXQueryVersionReq);
    737 
    738     major = req->majorVersion;
    739     minor = req->minorVersion;
    740     (void) major;
    741     (void) minor;
    742 
    743     /*
    744      ** Server should take into consideration the version numbers sent by the
    745      ** client if it wants to work with older clients; however, in this
    746      ** implementation the server just returns its version number.
    747      */
    748     reply = (xGLXQueryVersionReply) {
    749         .type = X_Reply,
    750         .sequenceNumber = client->sequence,
    751         .length = 0,
    752         .majorVersion = SERVER_GLX_MAJOR_VERSION,
    753         .minorVersion = SERVER_GLX_MINOR_VERSION
    754     };
    755 
    756     if (client->swapped) {
    757         __GLX_DECLARE_SWAP_VARIABLES;
    758         __GLX_SWAP_SHORT(&reply.sequenceNumber);
    759         __GLX_SWAP_INT(&reply.length);
    760         __GLX_SWAP_INT(&reply.majorVersion);
    761         __GLX_SWAP_INT(&reply.minorVersion);
    762     }
    763 
    764     WriteToClient(client, sz_xGLXQueryVersionReply, &reply);
    765     return Success;
    766 }
    767 
    768 int
    769 __glXDisp_WaitGL(__GLXclientState * cl, GLbyte * pc)
    770 {
    771     xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
    772     GLXContextTag tag;
    773     __GLXcontext *glxc = NULL;
    774     int error;
    775 
    776     tag = req->contextTag;
    777     if (tag) {
    778         glxc = __glXLookupContextByTag(cl, tag);
    779         if (!glxc)
    780             return __glXError(GLXBadContextTag);
    781 
    782         if (!__glXForceCurrent(cl, req->contextTag, &error))
    783             return error;
    784 
    785         glFinish();
    786     }
    787 
    788     if (glxc && glxc->drawPriv && glxc->drawPriv->waitGL)
    789         (*glxc->drawPriv->waitGL) (glxc->drawPriv);
    790 
    791     return Success;
    792 }
    793 
    794 int
    795 __glXDisp_WaitX(__GLXclientState * cl, GLbyte * pc)
    796 {
    797     xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
    798     GLXContextTag tag;
    799     __GLXcontext *glxc = NULL;
    800     int error;
    801 
    802     tag = req->contextTag;
    803     if (tag) {
    804         glxc = __glXLookupContextByTag(cl, tag);
    805         if (!glxc)
    806             return __glXError(GLXBadContextTag);
    807 
    808         if (!__glXForceCurrent(cl, req->contextTag, &error))
    809             return error;
    810     }
    811 
    812     if (glxc && glxc->drawPriv && glxc->drawPriv->waitX)
    813         (*glxc->drawPriv->waitX) (glxc->drawPriv);
    814 
    815     return Success;
    816 }
    817 
    818 int
    819 __glXDisp_CopyContext(__GLXclientState * cl, GLbyte * pc)
    820 {
    821     ClientPtr client = cl->client;
    822     xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
    823     GLXContextID source;
    824     GLXContextID dest;
    825     GLXContextTag tag;
    826     unsigned long mask;
    827     __GLXcontext *src, *dst;
    828     int error;
    829 
    830     source = req->source;
    831     dest = req->dest;
    832     tag = req->contextTag;
    833     mask = req->mask;
    834     if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error))
    835         return error;
    836     if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error))
    837         return error;
    838 
    839     /*
    840      ** They must be in the same address space, and same screen.
    841      ** NOTE: no support for direct rendering contexts here.
    842      */
    843     if (src->isDirect || dst->isDirect || (src->pGlxScreen != dst->pGlxScreen)) {
    844         client->errorValue = source;
    845         return BadMatch;
    846     }
    847 
    848     /*
    849      ** The destination context must not be current for any client.
    850      */
    851     if (dst->currentClient) {
    852         client->errorValue = dest;
    853         return BadAccess;
    854     }
    855 
    856     if (tag) {
    857         __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
    858 
    859         if (!tagcx) {
    860             return __glXError(GLXBadContextTag);
    861         }
    862         if (tagcx != src) {
    863             /*
    864              ** This would be caused by a faulty implementation of the client
    865              ** library.
    866              */
    867             return BadMatch;
    868         }
    869         /*
    870          ** In this case, glXCopyContext is in both GL and X streams, in terms
    871          ** of sequentiality.
    872          */
    873         if (__glXForceCurrent(cl, tag, &error)) {
    874             /*
    875              ** Do whatever is needed to make sure that all preceding requests
    876              ** in both streams are completed before the copy is executed.
    877              */
    878             glFinish();
    879         }
    880         else {
    881             return error;
    882         }
    883     }
    884     /*
    885      ** Issue copy.  The only reason for failure is a bad mask.
    886      */
    887     if (!(*dst->copy) (dst, src, mask)) {
    888         client->errorValue = mask;
    889         return BadValue;
    890     }
    891     return Success;
    892 }
    893 
    894 enum {
    895     GLX_VIS_CONFIG_UNPAIRED = 18,
    896     GLX_VIS_CONFIG_PAIRED = 22
    897 };
    898 
    899 enum {
    900     GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED
    901 };
    902 
    903 int
    904 __glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc)
    905 {
    906     xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
    907     ClientPtr client = cl->client;
    908     xGLXGetVisualConfigsReply reply;
    909     __GLXscreen *pGlxScreen;
    910     __GLXconfig *modes;
    911     CARD32 buf[GLX_VIS_CONFIG_TOTAL];
    912     int p, i, err;
    913 
    914     __GLX_DECLARE_SWAP_VARIABLES;
    915     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
    916 
    917     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
    918         return err;
    919 
    920     reply = (xGLXGetVisualConfigsReply) {
    921         .type = X_Reply,
    922         .sequenceNumber = client->sequence,
    923         .length = (pGlxScreen->numVisuals *
    924                    __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2,
    925         .numVisuals = pGlxScreen->numVisuals,
    926         .numProps = GLX_VIS_CONFIG_TOTAL
    927     };
    928 
    929     if (client->swapped) {
    930         __GLX_SWAP_SHORT(&reply.sequenceNumber);
    931         __GLX_SWAP_INT(&reply.length);
    932         __GLX_SWAP_INT(&reply.numVisuals);
    933         __GLX_SWAP_INT(&reply.numProps);
    934     }
    935 
    936     WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply);
    937 
    938     for (i = 0; i < pGlxScreen->numVisuals; i++) {
    939         modes = pGlxScreen->visuals[i];
    940 
    941         p = 0;
    942         buf[p++] = modes->visualID;
    943         buf[p++] = glxConvertToXVisualType(modes->visualType);
    944         buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE;
    945 
    946         buf[p++] = modes->redBits;
    947         buf[p++] = modes->greenBits;
    948         buf[p++] = modes->blueBits;
    949         buf[p++] = modes->alphaBits;
    950         buf[p++] = modes->accumRedBits;
    951         buf[p++] = modes->accumGreenBits;
    952         buf[p++] = modes->accumBlueBits;
    953         buf[p++] = modes->accumAlphaBits;
    954 
    955         buf[p++] = modes->doubleBufferMode;
    956         buf[p++] = modes->stereoMode;
    957 
    958         buf[p++] = modes->rgbBits;
    959         buf[p++] = modes->depthBits;
    960         buf[p++] = modes->stencilBits;
    961         buf[p++] = modes->numAuxBuffers;
    962         buf[p++] = modes->level;
    963 
    964         assert(p == GLX_VIS_CONFIG_UNPAIRED);
    965         /*
    966          ** Add token/value pairs for extensions.
    967          */
    968         buf[p++] = GLX_VISUAL_CAVEAT_EXT;
    969         buf[p++] = modes->visualRating;
    970         buf[p++] = GLX_TRANSPARENT_TYPE;
    971         buf[p++] = modes->transparentPixel;
    972         buf[p++] = GLX_TRANSPARENT_RED_VALUE;
    973         buf[p++] = modes->transparentRed;
    974         buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
    975         buf[p++] = modes->transparentGreen;
    976         buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
    977         buf[p++] = modes->transparentBlue;
    978         buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
    979         buf[p++] = modes->transparentAlpha;
    980         buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
    981         buf[p++] = modes->transparentIndex;
    982         buf[p++] = GLX_SAMPLES_SGIS;
    983         buf[p++] = modes->samples;
    984         buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
    985         buf[p++] = modes->sampleBuffers;
    986         buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
    987         buf[p++] = modes->visualSelectGroup;
    988         /* Add attribute only if its value is not default. */
    989         if (modes->sRGBCapable != GL_FALSE) {
    990             buf[p++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT;
    991             buf[p++] = modes->sRGBCapable;
    992         }
    993         /* Pad with zeroes, so that attributes count is constant. */
    994         while (p < GLX_VIS_CONFIG_TOTAL) {
    995             buf[p++] = 0;
    996         }
    997 
    998         assert(p == GLX_VIS_CONFIG_TOTAL);
    999         if (client->swapped) {
   1000             __GLX_SWAP_INT_ARRAY(buf, p);
   1001         }
   1002         WriteToClient(client, __GLX_SIZE_CARD32 * p, buf);
   1003     }
   1004     return Success;
   1005 }
   1006 
   1007 #define __GLX_TOTAL_FBCONFIG_ATTRIBS (44)
   1008 #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
   1009 /**
   1010  * Send the set of GLXFBConfigs to the client.  There is not currently
   1011  * and interface into the driver on the server-side to get GLXFBConfigs,
   1012  * so we "invent" some based on the \c __GLXvisualConfig structures that
   1013  * the driver does supply.
   1014  *
   1015  * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
   1016  * is the same, so this routine pulls double duty.
   1017  */
   1018 
   1019 static int
   1020 DoGetFBConfigs(__GLXclientState * cl, unsigned screen)
   1021 {
   1022     ClientPtr client = cl->client;
   1023     xGLXGetFBConfigsReply reply;
   1024     __GLXscreen *pGlxScreen;
   1025     CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
   1026     int p, err;
   1027     __GLXconfig *modes;
   1028 
   1029     __GLX_DECLARE_SWAP_VARIABLES;
   1030     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
   1031 
   1032     if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
   1033         return err;
   1034 
   1035     reply = (xGLXGetFBConfigsReply) {
   1036         .type = X_Reply,
   1037         .sequenceNumber = client->sequence,
   1038         .length = __GLX_FBCONFIG_ATTRIBS_LENGTH * pGlxScreen->numFBConfigs,
   1039         .numFBConfigs = pGlxScreen->numFBConfigs,
   1040         .numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS
   1041     };
   1042 
   1043     if (client->swapped) {
   1044         __GLX_SWAP_SHORT(&reply.sequenceNumber);
   1045         __GLX_SWAP_INT(&reply.length);
   1046         __GLX_SWAP_INT(&reply.numFBConfigs);
   1047         __GLX_SWAP_INT(&reply.numAttribs);
   1048     }
   1049 
   1050     WriteToClient(client, sz_xGLXGetFBConfigsReply, &reply);
   1051 
   1052     for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
   1053         p = 0;
   1054 
   1055 #define WRITE_PAIR(tag,value) \
   1056     do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
   1057 
   1058         WRITE_PAIR(GLX_VISUAL_ID, modes->visualID);
   1059         WRITE_PAIR(GLX_FBCONFIG_ID, modes->fbconfigID);
   1060         WRITE_PAIR(GLX_X_RENDERABLE,
   1061                    (modes->drawableType & (GLX_WINDOW_BIT | GLX_PIXMAP_BIT)
   1062                     ? GL_TRUE
   1063                     : GL_FALSE));
   1064 
   1065         WRITE_PAIR(GLX_RGBA,
   1066                    (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE);
   1067         WRITE_PAIR(GLX_RENDER_TYPE, modes->renderType);
   1068         WRITE_PAIR(GLX_DOUBLEBUFFER, modes->doubleBufferMode);
   1069         WRITE_PAIR(GLX_STEREO, modes->stereoMode);
   1070 
   1071         WRITE_PAIR(GLX_BUFFER_SIZE, modes->rgbBits);
   1072         WRITE_PAIR(GLX_LEVEL, modes->level);
   1073         WRITE_PAIR(GLX_AUX_BUFFERS, modes->numAuxBuffers);
   1074         WRITE_PAIR(GLX_RED_SIZE, modes->redBits);
   1075         WRITE_PAIR(GLX_GREEN_SIZE, modes->greenBits);
   1076         WRITE_PAIR(GLX_BLUE_SIZE, modes->blueBits);
   1077         WRITE_PAIR(GLX_ALPHA_SIZE, modes->alphaBits);
   1078         WRITE_PAIR(GLX_ACCUM_RED_SIZE, modes->accumRedBits);
   1079         WRITE_PAIR(GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits);
   1080         WRITE_PAIR(GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits);
   1081         WRITE_PAIR(GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits);
   1082         WRITE_PAIR(GLX_DEPTH_SIZE, modes->depthBits);
   1083         WRITE_PAIR(GLX_STENCIL_SIZE, modes->stencilBits);
   1084         WRITE_PAIR(GLX_X_VISUAL_TYPE, modes->visualType);
   1085         WRITE_PAIR(GLX_CONFIG_CAVEAT, modes->visualRating);
   1086         WRITE_PAIR(GLX_TRANSPARENT_TYPE, modes->transparentPixel);
   1087         WRITE_PAIR(GLX_TRANSPARENT_RED_VALUE, modes->transparentRed);
   1088         WRITE_PAIR(GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen);
   1089         WRITE_PAIR(GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue);
   1090         WRITE_PAIR(GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha);
   1091         WRITE_PAIR(GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex);
   1092         WRITE_PAIR(GLX_SWAP_METHOD_OML, modes->swapMethod);
   1093         WRITE_PAIR(GLX_SAMPLES_SGIS, modes->samples);
   1094         WRITE_PAIR(GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers);
   1095         WRITE_PAIR(GLX_VISUAL_SELECT_GROUP_SGIX, modes->visualSelectGroup);
   1096         WRITE_PAIR(GLX_DRAWABLE_TYPE, modes->drawableType);
   1097         WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb);
   1098         WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba);
   1099         WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture);
   1100         WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT,
   1101                    modes->bindToTextureTargets);
   1102 	/* can't report honestly until mesa is fixed */
   1103 	WRITE_PAIR(GLX_Y_INVERTED_EXT, GLX_DONT_CARE);
   1104 	if (modes->drawableType & GLX_PBUFFER_BIT) {
   1105 	    WRITE_PAIR(GLX_MAX_PBUFFER_WIDTH, modes->maxPbufferWidth);
   1106 	    WRITE_PAIR(GLX_MAX_PBUFFER_HEIGHT, modes->maxPbufferHeight);
   1107 	    WRITE_PAIR(GLX_MAX_PBUFFER_PIXELS, modes->maxPbufferPixels);
   1108 	    WRITE_PAIR(GLX_OPTIMAL_PBUFFER_WIDTH_SGIX,
   1109 		       modes->optimalPbufferWidth);
   1110 	    WRITE_PAIR(GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX,
   1111 		       modes->optimalPbufferHeight);
   1112 	}
   1113         /* Add attribute only if its value is not default. */
   1114         if (modes->sRGBCapable != GL_FALSE) {
   1115             WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, modes->sRGBCapable);
   1116         }
   1117         /* Pad the remaining place with zeroes, so that attributes count is constant. */
   1118         while (p < __GLX_FBCONFIG_ATTRIBS_LENGTH) {
   1119             WRITE_PAIR(0, 0);
   1120         }
   1121         assert(p == __GLX_FBCONFIG_ATTRIBS_LENGTH);
   1122 
   1123         if (client->swapped) {
   1124             __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
   1125         }
   1126         WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
   1127                       (char *) buf);
   1128     }
   1129     return Success;
   1130 }
   1131 
   1132 int
   1133 __glXDisp_GetFBConfigs(__GLXclientState * cl, GLbyte * pc)
   1134 {
   1135     xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
   1136 
   1137     return DoGetFBConfigs(cl, req->screen);
   1138 }
   1139 
   1140 int
   1141 __glXDisp_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc)
   1142 {
   1143     ClientPtr client = cl->client;
   1144     xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
   1145 
   1146     /* work around mesa bug, don't use REQUEST_SIZE_MATCH */
   1147     REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq);
   1148     return DoGetFBConfigs(cl, req->screen);
   1149 }
   1150 
   1151 GLboolean
   1152 __glXDrawableInit(__GLXdrawable * drawable,
   1153                   __GLXscreen * screen, DrawablePtr pDraw, int type,
   1154                   XID drawId, __GLXconfig * config)
   1155 {
   1156     drawable->pDraw = pDraw;
   1157     drawable->type = type;
   1158     drawable->drawId = drawId;
   1159     drawable->config = config;
   1160     drawable->eventMask = 0;
   1161 
   1162     return GL_TRUE;
   1163 }
   1164 
   1165 void
   1166 __glXDrawableRelease(__GLXdrawable * drawable)
   1167 {
   1168 }
   1169 
   1170 static int
   1171 DoCreateGLXDrawable(ClientPtr client, __GLXscreen * pGlxScreen,
   1172                     __GLXconfig * config, DrawablePtr pDraw, XID drawableId,
   1173                     XID glxDrawableId, int type)
   1174 {
   1175     __GLXdrawable *pGlxDraw;
   1176 
   1177     if (pGlxScreen->pScreen != pDraw->pScreen)
   1178         return BadMatch;
   1179 
   1180     pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
   1181                                           drawableId, type,
   1182                                           glxDrawableId, config);
   1183     if (pGlxDraw == NULL)
   1184         return BadAlloc;
   1185 
   1186     if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw))
   1187         return BadAlloc;
   1188 
   1189     /*
   1190      * Windows aren't refcounted, so track both the X and the GLX window
   1191      * so we get called regardless of destruction order.
   1192      */
   1193     if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW &&
   1194         !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw))
   1195         return BadAlloc;
   1196 
   1197     return Success;
   1198 }
   1199 
   1200 static int
   1201 DoCreateGLXPixmap(ClientPtr client, __GLXscreen * pGlxScreen,
   1202                   __GLXconfig * config, XID drawableId, XID glxDrawableId)
   1203 {
   1204     DrawablePtr pDraw;
   1205     int err;
   1206 
   1207     err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
   1208     if (err != Success) {
   1209         client->errorValue = drawableId;
   1210         return err;
   1211     }
   1212     if (pDraw->type != DRAWABLE_PIXMAP) {
   1213         client->errorValue = drawableId;
   1214         return BadPixmap;
   1215     }
   1216 
   1217     err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
   1218                               glxDrawableId, GLX_DRAWABLE_PIXMAP);
   1219 
   1220     if (err == Success)
   1221         ((PixmapPtr) pDraw)->refcnt++;
   1222 
   1223     return err;
   1224 }
   1225 
   1226 static void
   1227 determineTextureTarget(ClientPtr client, XID glxDrawableID,
   1228                        CARD32 *attribs, CARD32 numAttribs)
   1229 {
   1230     GLenum target = 0;
   1231     GLenum format = 0;
   1232     int i, err;
   1233     __GLXdrawable *pGlxDraw;
   1234 
   1235     if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP,
   1236                           DixWriteAccess, &pGlxDraw, &err))
   1237         /* We just added it in CreatePixmap, so we should never get here. */
   1238         return;
   1239 
   1240     for (i = 0; i < numAttribs; i++) {
   1241         if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
   1242             switch (attribs[2 * i + 1]) {
   1243             case GLX_TEXTURE_2D_EXT:
   1244                 target = GL_TEXTURE_2D;
   1245                 break;
   1246             case GLX_TEXTURE_RECTANGLE_EXT:
   1247                 target = GL_TEXTURE_RECTANGLE_ARB;
   1248                 break;
   1249             }
   1250         }
   1251 
   1252         if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
   1253             format = attribs[2 * i + 1];
   1254     }
   1255 
   1256     if (!target) {
   1257         int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
   1258 
   1259         if (h & (h - 1) || w & (w - 1))
   1260             target = GL_TEXTURE_RECTANGLE_ARB;
   1261         else
   1262             target = GL_TEXTURE_2D;
   1263     }
   1264 
   1265     pGlxDraw->target = target;
   1266     pGlxDraw->format = format;
   1267 }
   1268 
   1269 int
   1270 __glXDisp_CreateGLXPixmap(__GLXclientState * cl, GLbyte * pc)
   1271 {
   1272     xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
   1273     __GLXconfig *config;
   1274     __GLXscreen *pGlxScreen;
   1275     int err;
   1276 
   1277     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
   1278         return err;
   1279     if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
   1280         return err;
   1281 
   1282     return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
   1283                              req->pixmap, req->glxpixmap);
   1284 }
   1285 
   1286 int
   1287 __glXDisp_CreatePixmap(__GLXclientState * cl, GLbyte * pc)
   1288 {
   1289     ClientPtr client = cl->client;
   1290     xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
   1291     __GLXconfig *config;
   1292     __GLXscreen *pGlxScreen;
   1293     int err;
   1294 
   1295     REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq);
   1296     if (req->numAttribs > (UINT32_MAX >> 3)) {
   1297         client->errorValue = req->numAttribs;
   1298         return BadValue;
   1299     }
   1300     REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3);
   1301 
   1302     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
   1303         return err;
   1304     if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
   1305         return err;
   1306 
   1307     err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
   1308                             req->pixmap, req->glxpixmap);
   1309     if (err != Success)
   1310         return err;
   1311 
   1312     determineTextureTarget(cl->client, req->glxpixmap,
   1313                            (CARD32 *) (req + 1), req->numAttribs);
   1314 
   1315     return Success;
   1316 }
   1317 
   1318 int
   1319 __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState * cl, GLbyte * pc)
   1320 {
   1321     ClientPtr client = cl->client;
   1322     xGLXCreateGLXPixmapWithConfigSGIXReq *req =
   1323         (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
   1324     __GLXconfig *config;
   1325     __GLXscreen *pGlxScreen;
   1326     int err;
   1327 
   1328     REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq);
   1329 
   1330     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
   1331         return err;
   1332     if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
   1333         return err;
   1334 
   1335     return DoCreateGLXPixmap(cl->client, pGlxScreen,
   1336                              config, req->pixmap, req->glxpixmap);
   1337 }
   1338 
   1339 static int
   1340 DoDestroyDrawable(__GLXclientState * cl, XID glxdrawable, int type)
   1341 {
   1342     __GLXdrawable *pGlxDraw;
   1343     int err;
   1344 
   1345     if (!validGlxDrawable(cl->client, glxdrawable, type,
   1346                           DixDestroyAccess, &pGlxDraw, &err))
   1347         return err;
   1348 
   1349     FreeResource(glxdrawable, FALSE);
   1350 
   1351     return Success;
   1352 }
   1353 
   1354 int
   1355 __glXDisp_DestroyGLXPixmap(__GLXclientState * cl, GLbyte * pc)
   1356 {
   1357     xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
   1358 
   1359     return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
   1360 }
   1361 
   1362 int
   1363 __glXDisp_DestroyPixmap(__GLXclientState * cl, GLbyte * pc)
   1364 {
   1365     ClientPtr client = cl->client;
   1366     xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
   1367 
   1368     /* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set
   1369      * length to 3 instead of 2 */
   1370     REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq);
   1371 
   1372     return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
   1373 }
   1374 
   1375 static int
   1376 DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
   1377                 int width, int height, XID glxDrawableId)
   1378 {
   1379     __GLXconfig *config;
   1380     __GLXscreen *pGlxScreen;
   1381     PixmapPtr pPixmap;
   1382     int err;
   1383 
   1384     if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
   1385         return err;
   1386     if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
   1387         return err;
   1388 
   1389     pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
   1390                                                     width, height,
   1391                                                     config->rgbBits, 0);
   1392     if (!pPixmap)
   1393         return BadAlloc;
   1394 
   1395     /* Assign the pixmap the same id as the pbuffer and add it as a
   1396      * resource so it and the DRI2 drawable will be reclaimed when the
   1397      * pbuffer is destroyed. */
   1398     pPixmap->drawable.id = glxDrawableId;
   1399     if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap))
   1400         return BadAlloc;
   1401 
   1402     return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
   1403                                glxDrawableId, glxDrawableId,
   1404                                GLX_DRAWABLE_PBUFFER);
   1405 }
   1406 
   1407 int
   1408 __glXDisp_CreatePbuffer(__GLXclientState * cl, GLbyte * pc)
   1409 {
   1410     ClientPtr client = cl->client;
   1411     xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
   1412     CARD32 *attrs;
   1413     int width, height, i;
   1414 
   1415     REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq);
   1416     if (req->numAttribs > (UINT32_MAX >> 3)) {
   1417         client->errorValue = req->numAttribs;
   1418         return BadValue;
   1419     }
   1420     REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3);
   1421 
   1422     attrs = (CARD32 *) (req + 1);
   1423     width = 0;
   1424     height = 0;
   1425 
   1426     for (i = 0; i < req->numAttribs; i++) {
   1427         switch (attrs[i * 2]) {
   1428         case GLX_PBUFFER_WIDTH:
   1429             width = attrs[i * 2 + 1];
   1430             break;
   1431         case GLX_PBUFFER_HEIGHT:
   1432             height = attrs[i * 2 + 1];
   1433             break;
   1434         case GLX_LARGEST_PBUFFER:
   1435             /* FIXME: huh... */
   1436             break;
   1437         }
   1438     }
   1439 
   1440     return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
   1441                            width, height, req->pbuffer);
   1442 }
   1443 
   1444 int
   1445 __glXDisp_CreateGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc)
   1446 {
   1447     ClientPtr client = cl->client;
   1448     xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
   1449 
   1450     REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq);
   1451 
   1452     /*
   1453      * We should really handle attributes correctly, but this extension
   1454      * is so rare I have difficulty caring.
   1455      */
   1456     return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
   1457                            req->width, req->height, req->pbuffer);
   1458 }
   1459 
   1460 int
   1461 __glXDisp_DestroyPbuffer(__GLXclientState * cl, GLbyte * pc)
   1462 {
   1463     ClientPtr client = cl->client;
   1464     xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
   1465 
   1466     REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq);
   1467 
   1468     return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
   1469 }
   1470 
   1471 int
   1472 __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc)
   1473 {
   1474     ClientPtr client = cl->client;
   1475     xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
   1476 
   1477     REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq);
   1478 
   1479     return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
   1480 }
   1481 
   1482 static int
   1483 DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
   1484                            int numAttribs, CARD32 *attribs)
   1485 {
   1486     __GLXdrawable *pGlxDraw;
   1487     int i, err;
   1488 
   1489     if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY,
   1490                           DixSetAttrAccess, &pGlxDraw, &err))
   1491         return err;
   1492 
   1493     for (i = 0; i < numAttribs; i++) {
   1494         switch (attribs[i * 2]) {
   1495         case GLX_EVENT_MASK:
   1496             /* All we do is to record the event mask so we can send it
   1497              * back when queried.  We never actually clobber the
   1498              * pbuffers, so we never need to send out the event. */
   1499             pGlxDraw->eventMask = attribs[i * 2 + 1];
   1500             break;
   1501         }
   1502     }
   1503 
   1504     return Success;
   1505 }
   1506 
   1507 int
   1508 __glXDisp_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
   1509 {
   1510     ClientPtr client = cl->client;
   1511     xGLXChangeDrawableAttributesReq *req =
   1512         (xGLXChangeDrawableAttributesReq *) pc;
   1513 
   1514     REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq);
   1515     if (req->numAttribs > (UINT32_MAX >> 3)) {
   1516         client->errorValue = req->numAttribs;
   1517         return BadValue;
   1518     }
   1519 #if 0
   1520     /* mesa sends an additional 8 bytes */
   1521     REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3);
   1522 #else
   1523     if (((sizeof(xGLXChangeDrawableAttributesReq) +
   1524           (req->numAttribs << 3)) >> 2) < client->req_len)
   1525         return BadLength;
   1526 #endif
   1527 
   1528     return DoChangeDrawableAttributes(cl->client, req->drawable,
   1529                                       req->numAttribs, (CARD32 *) (req + 1));
   1530 }
   1531 
   1532 int
   1533 __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc)
   1534 {
   1535     ClientPtr client = cl->client;
   1536     xGLXChangeDrawableAttributesSGIXReq *req =
   1537         (xGLXChangeDrawableAttributesSGIXReq *) pc;
   1538 
   1539     REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq);
   1540     if (req->numAttribs > (UINT32_MAX >> 3)) {
   1541         client->errorValue = req->numAttribs;
   1542         return BadValue;
   1543     }
   1544     REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq,
   1545                        req->numAttribs << 3);
   1546 
   1547     return DoChangeDrawableAttributes(cl->client, req->drawable,
   1548                                       req->numAttribs, (CARD32 *) (req + 1));
   1549 }
   1550 
   1551 int
   1552 __glXDisp_CreateWindow(__GLXclientState * cl, GLbyte * pc)
   1553 {
   1554     xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
   1555     __GLXconfig *config;
   1556     __GLXscreen *pGlxScreen;
   1557     ClientPtr client = cl->client;
   1558     DrawablePtr pDraw;
   1559     int err;
   1560 
   1561     REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq);
   1562     if (req->numAttribs > (UINT32_MAX >> 3)) {
   1563         client->errorValue = req->numAttribs;
   1564         return BadValue;
   1565     }
   1566     REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3);
   1567 
   1568     if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
   1569         return err;
   1570     if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
   1571         return err;
   1572 
   1573     err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess);
   1574     if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
   1575         client->errorValue = req->window;
   1576         return BadWindow;
   1577     }
   1578 
   1579     if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
   1580         return err;
   1581 
   1582     return DoCreateGLXDrawable(client, pGlxScreen, config,
   1583                                pDraw, req->window,
   1584                                req->glxwindow, GLX_DRAWABLE_WINDOW);
   1585 }
   1586 
   1587 int
   1588 __glXDisp_DestroyWindow(__GLXclientState * cl, GLbyte * pc)
   1589 {
   1590     ClientPtr client = cl->client;
   1591     xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
   1592 
   1593     /* mesa's glXDestroyWindow used to set length to 3 instead of 2 */
   1594     REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq);
   1595 
   1596     return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
   1597 }
   1598 
   1599 /*****************************************************************************/
   1600 
   1601 /*
   1602 ** NOTE: There is no portable implementation for swap buffers as of
   1603 ** this time that is of value.  Consequently, this code must be
   1604 ** implemented by somebody other than SGI.
   1605 */
   1606 int
   1607 __glXDisp_SwapBuffers(__GLXclientState * cl, GLbyte * pc)
   1608 {
   1609     ClientPtr client = cl->client;
   1610     xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
   1611     GLXContextTag tag;
   1612     XID drawId;
   1613     __GLXcontext *glxc = NULL;
   1614     __GLXdrawable *pGlxDraw;
   1615     int error;
   1616 
   1617     tag = req->contextTag;
   1618     drawId = req->drawable;
   1619     if (tag) {
   1620         glxc = __glXLookupContextByTag(cl, tag);
   1621         if (!glxc) {
   1622             return __glXError(GLXBadContextTag);
   1623         }
   1624         /*
   1625          ** The calling thread is swapping its current drawable.  In this case,
   1626          ** glxSwapBuffers is in both GL and X streams, in terms of
   1627          ** sequentiality.
   1628          */
   1629         if (__glXForceCurrent(cl, tag, &error)) {
   1630             /*
   1631              ** Do whatever is needed to make sure that all preceding requests
   1632              ** in both streams are completed before the swap is executed.
   1633              */
   1634             glFinish();
   1635         }
   1636         else {
   1637             return error;
   1638         }
   1639     }
   1640 
   1641     pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
   1642     if (pGlxDraw == NULL)
   1643         return error;
   1644 
   1645     if (pGlxDraw->type == DRAWABLE_WINDOW &&
   1646         (*pGlxDraw->swapBuffers) (cl->client, pGlxDraw) == GL_FALSE)
   1647         return __glXError(GLXBadDrawable);
   1648 
   1649     return Success;
   1650 }
   1651 
   1652 static int
   1653 DoQueryContext(__GLXclientState * cl, GLXContextID gcId)
   1654 {
   1655     ClientPtr client = cl->client;
   1656     __GLXcontext *ctx;
   1657     xGLXQueryContextInfoEXTReply reply;
   1658     int nProps = 5;
   1659     int sendBuf[nProps * 2];
   1660     int nReplyBytes;
   1661     int err;
   1662 
   1663     if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err))
   1664         return err;
   1665 
   1666     reply = (xGLXQueryContextInfoEXTReply) {
   1667         .type = X_Reply,
   1668         .sequenceNumber = client->sequence,
   1669         .length = nProps << 1,
   1670         .n = nProps
   1671     };
   1672 
   1673     nReplyBytes = reply.length << 2;
   1674     sendBuf[0] = GLX_SHARE_CONTEXT_EXT;
   1675     sendBuf[1] = (int) (ctx->share_id);
   1676     sendBuf[2] = GLX_VISUAL_ID_EXT;
   1677     sendBuf[3] = (int) (ctx->config ? ctx->config->visualID : 0);
   1678     sendBuf[4] = GLX_SCREEN_EXT;
   1679     sendBuf[5] = (int) (ctx->pGlxScreen->pScreen->myNum);
   1680     sendBuf[6] = GLX_FBCONFIG_ID;
   1681     sendBuf[7] = (int) (ctx->config ? ctx->config->fbconfigID : 0);
   1682     sendBuf[8] = GLX_RENDER_TYPE;
   1683     sendBuf[9] = (int) (ctx->renderType);
   1684 
   1685     if (client->swapped) {
   1686         int length = reply.length;
   1687 
   1688         __GLX_DECLARE_SWAP_VARIABLES;
   1689         __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
   1690         __GLX_SWAP_SHORT(&reply.sequenceNumber);
   1691         __GLX_SWAP_INT(&reply.length);
   1692         __GLX_SWAP_INT(&reply.n);
   1693         WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply);
   1694         __GLX_SWAP_INT_ARRAY((int *) sendBuf, length);
   1695         WriteToClient(client, length << 2, sendBuf);
   1696     }
   1697     else {
   1698         WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply);
   1699         WriteToClient(client, nReplyBytes, sendBuf);
   1700     }
   1701 
   1702     return Success;
   1703 }
   1704 
   1705 int
   1706 __glXDisp_QueryContextInfoEXT(__GLXclientState * cl, GLbyte * pc)
   1707 {
   1708     ClientPtr client = cl->client;
   1709     xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
   1710 
   1711     REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq);
   1712 
   1713     return DoQueryContext(cl, req->context);
   1714 }
   1715 
   1716 int
   1717 __glXDisp_QueryContext(__GLXclientState * cl, GLbyte * pc)
   1718 {
   1719     xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
   1720 
   1721     return DoQueryContext(cl, req->context);
   1722 }
   1723 
   1724 int
   1725 __glXDisp_BindTexImageEXT(__GLXclientState * cl, GLbyte * pc)
   1726 {
   1727     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
   1728     ClientPtr client = cl->client;
   1729     __GLXcontext *context;
   1730     __GLXdrawable *pGlxDraw;
   1731     GLXDrawable drawId;
   1732     int buffer;
   1733     int error;
   1734     CARD32 num_attribs;
   1735 
   1736     if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len)
   1737         return BadLength;
   1738 
   1739     pc += __GLX_VENDPRIV_HDR_SIZE;
   1740 
   1741     drawId = *((CARD32 *) (pc));
   1742     buffer = *((INT32 *) (pc + 4));
   1743     num_attribs = *((CARD32 *) (pc + 8));
   1744     if (num_attribs > (UINT32_MAX >> 3)) {
   1745         client->errorValue = num_attribs;
   1746         return BadValue;
   1747     }
   1748     REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 12 + (num_attribs << 3));
   1749 
   1750     if (buffer != GLX_FRONT_LEFT_EXT)
   1751         return __glXError(GLXBadPixmap);
   1752 
   1753     context = __glXForceCurrent(cl, req->contextTag, &error);
   1754     if (!context)
   1755         return error;
   1756 
   1757     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
   1758                           DixReadAccess, &pGlxDraw, &error))
   1759         return error;
   1760 
   1761     if (!context->bindTexImage)
   1762         return __glXError(GLXUnsupportedPrivateRequest);
   1763 
   1764     return context->bindTexImage(context, buffer, pGlxDraw);
   1765 }
   1766 
   1767 int
   1768 __glXDisp_ReleaseTexImageEXT(__GLXclientState * cl, GLbyte * pc)
   1769 {
   1770     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
   1771     ClientPtr client = cl->client;
   1772     __GLXdrawable *pGlxDraw;
   1773     __GLXcontext *context;
   1774     GLXDrawable drawId;
   1775     int buffer;
   1776     int error;
   1777 
   1778     REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8);
   1779 
   1780     pc += __GLX_VENDPRIV_HDR_SIZE;
   1781 
   1782     drawId = *((CARD32 *) (pc));
   1783     buffer = *((INT32 *) (pc + 4));
   1784 
   1785     context = __glXForceCurrent(cl, req->contextTag, &error);
   1786     if (!context)
   1787         return error;
   1788 
   1789     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
   1790                           DixReadAccess, &pGlxDraw, &error))
   1791         return error;
   1792 
   1793     if (!context->releaseTexImage)
   1794         return __glXError(GLXUnsupportedPrivateRequest);
   1795 
   1796     return context->releaseTexImage(context, buffer, pGlxDraw);
   1797 }
   1798 
   1799 int
   1800 __glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc)
   1801 {
   1802     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
   1803     GLXContextTag tag = req->contextTag;
   1804     __GLXcontext *glxc = NULL;
   1805     __GLXdrawable *pGlxDraw;
   1806     ClientPtr client = cl->client;
   1807     GLXDrawable drawId;
   1808     int error;
   1809     int x, y, width, height;
   1810 
   1811     (void) client;
   1812     (void) req;
   1813 
   1814     REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20);
   1815 
   1816     pc += __GLX_VENDPRIV_HDR_SIZE;
   1817 
   1818     drawId = *((CARD32 *) (pc));
   1819     x = *((INT32 *) (pc + 4));
   1820     y = *((INT32 *) (pc + 8));
   1821     width = *((INT32 *) (pc + 12));
   1822     height = *((INT32 *) (pc + 16));
   1823 
   1824     if (tag) {
   1825         glxc = __glXLookupContextByTag(cl, tag);
   1826         if (!glxc) {
   1827             return __glXError(GLXBadContextTag);
   1828         }
   1829         /*
   1830          ** The calling thread is swapping its current drawable.  In this case,
   1831          ** glxSwapBuffers is in both GL and X streams, in terms of
   1832          ** sequentiality.
   1833          */
   1834         if (__glXForceCurrent(cl, tag, &error)) {
   1835             /*
   1836              ** Do whatever is needed to make sure that all preceding requests
   1837              ** in both streams are completed before the swap is executed.
   1838              */
   1839             glFinish();
   1840         }
   1841         else {
   1842             return error;
   1843         }
   1844     }
   1845 
   1846     pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
   1847     if (!pGlxDraw)
   1848         return error;
   1849 
   1850     if (pGlxDraw == NULL ||
   1851         pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
   1852         pGlxDraw->copySubBuffer == NULL)
   1853         return __glXError(GLXBadDrawable);
   1854 
   1855     (*pGlxDraw->copySubBuffer) (pGlxDraw, x, y, width, height);
   1856 
   1857     return Success;
   1858 }
   1859 
   1860 /* hack for old glxext.h */
   1861 #ifndef GLX_STEREO_TREE_EXT
   1862 #define GLX_STEREO_TREE_EXT                 0x20F5
   1863 #endif
   1864 
   1865 /*
   1866 ** Get drawable attributes
   1867 */
   1868 static int
   1869 DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
   1870 {
   1871     ClientPtr client = cl->client;
   1872     xGLXGetDrawableAttributesReply reply;
   1873     __GLXdrawable *pGlxDraw = NULL;
   1874     DrawablePtr pDraw;
   1875     CARD32 attributes[20];
   1876     int num = 0, error;
   1877 
   1878     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
   1879                           DixGetAttrAccess, &pGlxDraw, &error)) {
   1880         /* hack for GLX 1.2 naked windows */
   1881         int err = dixLookupWindow((WindowPtr *)&pDraw, drawId, client,
   1882                                   DixGetAttrAccess);
   1883         if (err != Success)
   1884             return __glXError(GLXBadDrawable);
   1885     }
   1886     if (pGlxDraw)
   1887         pDraw = pGlxDraw->pDraw;
   1888 
   1889 #define ATTRIB(a, v) do { \
   1890     attributes[2*num] = (a); \
   1891     attributes[2*num+1] = (v); \
   1892     num++; \
   1893     } while (0)
   1894 
   1895     ATTRIB(GLX_Y_INVERTED_EXT, GL_FALSE);
   1896     ATTRIB(GLX_WIDTH, pDraw->width);
   1897     ATTRIB(GLX_HEIGHT, pDraw->height);
   1898     ATTRIB(GLX_SCREEN, pDraw->pScreen->myNum);
   1899     if (pGlxDraw) {
   1900         ATTRIB(GLX_TEXTURE_TARGET_EXT,
   1901                pGlxDraw->target == GL_TEXTURE_2D ?
   1902                 GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT);
   1903         ATTRIB(GLX_EVENT_MASK, pGlxDraw->eventMask);
   1904         ATTRIB(GLX_FBCONFIG_ID, pGlxDraw->config->fbconfigID);
   1905         if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
   1906             ATTRIB(GLX_PRESERVED_CONTENTS, GL_TRUE);
   1907         }
   1908         if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) {
   1909             ATTRIB(GLX_STEREO_TREE_EXT, 0);
   1910         }
   1911     }
   1912 
   1913     /* GLX_EXT_get_drawable_type */
   1914     if (!pGlxDraw || pGlxDraw->type == GLX_DRAWABLE_WINDOW)
   1915         ATTRIB(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT);
   1916     else if (pGlxDraw->type == GLX_DRAWABLE_PIXMAP)
   1917         ATTRIB(GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT);
   1918     else if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER)
   1919         ATTRIB(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
   1920 #undef ATTRIB
   1921 
   1922     reply = (xGLXGetDrawableAttributesReply) {
   1923         .type = X_Reply,
   1924         .sequenceNumber = client->sequence,
   1925         .length = num << 1,
   1926         .numAttribs = num
   1927     };
   1928 
   1929     if (client->swapped) {
   1930         int length = reply.length;
   1931 
   1932         __GLX_DECLARE_SWAP_VARIABLES;
   1933         __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
   1934         __GLX_SWAP_SHORT(&reply.sequenceNumber);
   1935         __GLX_SWAP_INT(&reply.length);
   1936         __GLX_SWAP_INT(&reply.numAttribs);
   1937         WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply);
   1938         __GLX_SWAP_INT_ARRAY((int *) attributes, length);
   1939         WriteToClient(client, length << 2, attributes);
   1940     }
   1941     else {
   1942         WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply);
   1943         WriteToClient(client, reply.length * sizeof(CARD32), attributes);
   1944     }
   1945 
   1946     return Success;
   1947 }
   1948 
   1949 int
   1950 __glXDisp_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
   1951 {
   1952     ClientPtr client = cl->client;
   1953     xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *) pc;
   1954 
   1955     /* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */
   1956     REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq);
   1957 
   1958     return DoGetDrawableAttributes(cl, req->drawable);
   1959 }
   1960 
   1961 int
   1962 __glXDisp_GetDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc)
   1963 {
   1964     ClientPtr client = cl->client;
   1965     xGLXGetDrawableAttributesSGIXReq *req =
   1966         (xGLXGetDrawableAttributesSGIXReq *) pc;
   1967 
   1968     REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq);
   1969 
   1970     return DoGetDrawableAttributes(cl, req->drawable);
   1971 }
   1972 
   1973 /************************************************************************/
   1974 
   1975 /*
   1976 ** Render and Renderlarge are not in the GLX API.  They are used by the GLX
   1977 ** client library to send batches of GL rendering commands.
   1978 */
   1979 
   1980 /*
   1981 ** Reset state used to keep track of large (multi-request) commands.
   1982 */
   1983 static void
   1984 ResetLargeCommandStatus(__GLXcontext *cx)
   1985 {
   1986     cx->largeCmdBytesSoFar = 0;
   1987     cx->largeCmdBytesTotal = 0;
   1988     cx->largeCmdRequestsSoFar = 0;
   1989     cx->largeCmdRequestsTotal = 0;
   1990 }
   1991 
   1992 /*
   1993 ** Execute all the drawing commands in a request.
   1994 */
   1995 int
   1996 __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
   1997 {
   1998     xGLXRenderReq *req;
   1999     ClientPtr client = cl->client;
   2000     int left, cmdlen, error;
   2001     int commandsDone;
   2002     CARD16 opcode;
   2003     __GLXrenderHeader *hdr;
   2004     __GLXcontext *glxc;
   2005 
   2006     __GLX_DECLARE_SWAP_VARIABLES;
   2007 
   2008     REQUEST_AT_LEAST_SIZE(xGLXRenderReq);
   2009 
   2010     req = (xGLXRenderReq *) pc;
   2011     if (client->swapped) {
   2012         __GLX_SWAP_SHORT(&req->length);
   2013         __GLX_SWAP_INT(&req->contextTag);
   2014     }
   2015 
   2016     glxc = __glXForceCurrent(cl, req->contextTag, &error);
   2017     if (!glxc) {
   2018         return error;
   2019     }
   2020 
   2021     commandsDone = 0;
   2022     pc += sz_xGLXRenderReq;
   2023     left = (req->length << 2) - sz_xGLXRenderReq;
   2024     while (left > 0) {
   2025         __GLXrenderSizeData entry;
   2026         int extra = 0;
   2027         __GLXdispatchRenderProcPtr proc;
   2028         int err;
   2029 
   2030         if (left < sizeof(__GLXrenderHeader))
   2031             return BadLength;
   2032 
   2033         /*
   2034          ** Verify that the header length and the overall length agree.
   2035          ** Also, each command must be word aligned.
   2036          */
   2037         hdr = (__GLXrenderHeader *) pc;
   2038         if (client->swapped) {
   2039             __GLX_SWAP_SHORT(&hdr->length);
   2040             __GLX_SWAP_SHORT(&hdr->opcode);
   2041         }
   2042         cmdlen = hdr->length;
   2043         opcode = hdr->opcode;
   2044 
   2045         if (left < cmdlen)
   2046             return BadLength;
   2047 
   2048         /*
   2049          ** Check for core opcodes and grab entry data.
   2050          */
   2051         err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry);
   2052         proc = (__GLXdispatchRenderProcPtr)
   2053             __glXGetProtocolDecodeFunction(&Render_dispatch_info,
   2054                                            opcode, client->swapped);
   2055 
   2056         if ((err < 0) || (proc == NULL)) {
   2057             client->errorValue = commandsDone;
   2058             return __glXError(GLXBadRenderRequest);
   2059         }
   2060 
   2061         if (cmdlen < entry.bytes) {
   2062             return BadLength;
   2063         }
   2064 
   2065         if (entry.varsize) {
   2066             /* variable size command */
   2067             extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE,
   2068                                       client->swapped,
   2069                                       left - __GLX_RENDER_HDR_SIZE);
   2070             if (extra < 0) {
   2071                 return BadLength;
   2072             }
   2073         }
   2074 
   2075         if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) {
   2076             return BadLength;
   2077         }
   2078 
   2079         /*
   2080          ** Skip over the header and execute the command.  We allow the
   2081          ** caller to trash the command memory.  This is useful especially
   2082          ** for things that require double alignment - they can just shift
   2083          ** the data towards lower memory (trashing the header) by 4 bytes
   2084          ** and achieve the required alignment.
   2085          */
   2086         (*proc) (pc + __GLX_RENDER_HDR_SIZE);
   2087         pc += cmdlen;
   2088         left -= cmdlen;
   2089         commandsDone++;
   2090     }
   2091     return Success;
   2092 }
   2093 
   2094 /*
   2095 ** Execute a large rendering request (one that spans multiple X requests).
   2096 */
   2097 int
   2098 __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
   2099 {
   2100     xGLXRenderLargeReq *req;
   2101     ClientPtr client = cl->client;
   2102     size_t dataBytes;
   2103     __GLXrenderLargeHeader *hdr;
   2104     __GLXcontext *glxc;
   2105     int error;
   2106     CARD16 opcode;
   2107 
   2108     __GLX_DECLARE_SWAP_VARIABLES;
   2109 
   2110     REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq);
   2111 
   2112     req = (xGLXRenderLargeReq *) pc;
   2113     if (client->swapped) {
   2114         __GLX_SWAP_SHORT(&req->length);
   2115         __GLX_SWAP_INT(&req->contextTag);
   2116         __GLX_SWAP_INT(&req->dataBytes);
   2117         __GLX_SWAP_SHORT(&req->requestNumber);
   2118         __GLX_SWAP_SHORT(&req->requestTotal);
   2119     }
   2120 
   2121     glxc = __glXForceCurrent(cl, req->contextTag, &error);
   2122     if (!glxc) {
   2123         return error;
   2124     }
   2125     if (safe_pad(req->dataBytes) < 0)
   2126         return BadLength;
   2127     dataBytes = req->dataBytes;
   2128 
   2129     /*
   2130      ** Check the request length.
   2131      */
   2132     if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) {
   2133         client->errorValue = req->length;
   2134         /* Reset in case this isn't 1st request. */
   2135         ResetLargeCommandStatus(glxc);
   2136         return BadLength;
   2137     }
   2138     pc += sz_xGLXRenderLargeReq;
   2139 
   2140     if (glxc->largeCmdRequestsSoFar == 0) {
   2141         __GLXrenderSizeData entry;
   2142         int extra = 0;
   2143         int left = (req->length << 2) - sz_xGLXRenderLargeReq;
   2144         int cmdlen;
   2145         int err;
   2146 
   2147         /*
   2148          ** This is the first request of a multi request command.
   2149          ** Make enough space in the buffer, then copy the entire request.
   2150          */
   2151         if (req->requestNumber != 1) {
   2152             client->errorValue = req->requestNumber;
   2153             return __glXError(GLXBadLargeRequest);
   2154         }
   2155 
   2156         if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE)
   2157             return BadLength;
   2158 
   2159         hdr = (__GLXrenderLargeHeader *) pc;
   2160         if (client->swapped) {
   2161             __GLX_SWAP_INT(&hdr->length);
   2162             __GLX_SWAP_INT(&hdr->opcode);
   2163         }
   2164         opcode = hdr->opcode;
   2165         if ((cmdlen = safe_pad(hdr->length)) < 0)
   2166             return BadLength;
   2167 
   2168         /*
   2169          ** Check for core opcodes and grab entry data.
   2170          */
   2171         err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry);
   2172         if (err < 0) {
   2173             client->errorValue = opcode;
   2174             return __glXError(GLXBadLargeRequest);
   2175         }
   2176 
   2177         if (entry.varsize) {
   2178             /*
   2179              ** If it's a variable-size command (a command whose length must
   2180              ** be computed from its parameters), all the parameters needed
   2181              ** will be in the 1st request, so it's okay to do this.
   2182              */
   2183             extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE,
   2184                                       client->swapped,
   2185                                       left - __GLX_RENDER_LARGE_HDR_SIZE);
   2186             if (extra < 0) {
   2187                 return BadLength;
   2188             }
   2189         }
   2190 
   2191         /* the +4 is safe because we know entry.bytes is small */
   2192         if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) {
   2193             return BadLength;
   2194         }
   2195 
   2196         /*
   2197          ** Make enough space in the buffer, then copy the entire request.
   2198          */
   2199         if (glxc->largeCmdBufSize < cmdlen) {
   2200 	    GLbyte *newbuf = glxc->largeCmdBuf;
   2201 
   2202 	    if (!(newbuf = realloc(newbuf, cmdlen)))
   2203 		return BadAlloc;
   2204 
   2205 	    glxc->largeCmdBuf = newbuf;
   2206             glxc->largeCmdBufSize = cmdlen;
   2207         }
   2208         memcpy(glxc->largeCmdBuf, pc, dataBytes);
   2209 
   2210         glxc->largeCmdBytesSoFar = dataBytes;
   2211         glxc->largeCmdBytesTotal = cmdlen;
   2212         glxc->largeCmdRequestsSoFar = 1;
   2213         glxc->largeCmdRequestsTotal = req->requestTotal;
   2214         return Success;
   2215 
   2216     }
   2217     else {
   2218         /*
   2219          ** We are receiving subsequent (i.e. not the first) requests of a
   2220          ** multi request command.
   2221          */
   2222         int bytesSoFar; /* including this packet */
   2223 
   2224         /*
   2225          ** Check the request number and the total request count.
   2226          */
   2227         if (req->requestNumber != glxc->largeCmdRequestsSoFar + 1) {
   2228             client->errorValue = req->requestNumber;
   2229             ResetLargeCommandStatus(glxc);
   2230             return __glXError(GLXBadLargeRequest);
   2231         }
   2232         if (req->requestTotal != glxc->largeCmdRequestsTotal) {
   2233             client->errorValue = req->requestTotal;
   2234             ResetLargeCommandStatus(glxc);
   2235             return __glXError(GLXBadLargeRequest);
   2236         }
   2237 
   2238         /*
   2239          ** Check that we didn't get too much data.
   2240          */
   2241         if ((bytesSoFar = safe_add(glxc->largeCmdBytesSoFar, dataBytes)) < 0) {
   2242             client->errorValue = dataBytes;
   2243             ResetLargeCommandStatus(glxc);
   2244             return __glXError(GLXBadLargeRequest);
   2245         }
   2246 
   2247         if (bytesSoFar > glxc->largeCmdBytesTotal) {
   2248             client->errorValue = dataBytes;
   2249             ResetLargeCommandStatus(glxc);
   2250             return __glXError(GLXBadLargeRequest);
   2251         }
   2252 
   2253         memcpy(glxc->largeCmdBuf + glxc->largeCmdBytesSoFar, pc, dataBytes);
   2254         glxc->largeCmdBytesSoFar += dataBytes;
   2255         glxc->largeCmdRequestsSoFar++;
   2256 
   2257         if (req->requestNumber == glxc->largeCmdRequestsTotal) {
   2258             __GLXdispatchRenderProcPtr proc;
   2259 
   2260             /*
   2261              ** This is the last request; it must have enough bytes to complete
   2262              ** the command.
   2263              */
   2264             /* NOTE: the pad macro below is needed because the client library
   2265              ** pads the total byte count, but not the per-request byte counts.
   2266              ** The Protocol Encoding says the total byte count should not be
   2267              ** padded, so a proposal will be made to the ARB to relax the
   2268              ** padding constraint on the total byte count, thus preserving
   2269              ** backward compatibility.  Meanwhile, the padding done below
   2270              ** fixes a bug that did not allow large commands of odd sizes to
   2271              ** be accepted by the server.
   2272              */
   2273             if (safe_pad(glxc->largeCmdBytesSoFar) != glxc->largeCmdBytesTotal) {
   2274                 client->errorValue = dataBytes;
   2275                 ResetLargeCommandStatus(glxc);
   2276                 return __glXError(GLXBadLargeRequest);
   2277             }
   2278             hdr = (__GLXrenderLargeHeader *) glxc->largeCmdBuf;
   2279             /*
   2280              ** The opcode and length field in the header had already been
   2281              ** swapped when the first request was received.
   2282              **
   2283              ** Use the opcode to index into the procedure table.
   2284              */
   2285             opcode = hdr->opcode;
   2286 
   2287             proc = (__GLXdispatchRenderProcPtr)
   2288                 __glXGetProtocolDecodeFunction(&Render_dispatch_info, opcode,
   2289                                                client->swapped);
   2290             if (proc == NULL) {
   2291                 client->errorValue = opcode;
   2292                 return __glXError(GLXBadLargeRequest);
   2293             }
   2294 
   2295             /*
   2296              ** Skip over the header and execute the command.
   2297              */
   2298             (*proc) (glxc->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
   2299 
   2300             /*
   2301              ** Reset for the next RenderLarge series.
   2302              */
   2303             ResetLargeCommandStatus(glxc);
   2304         }
   2305         else {
   2306             /*
   2307              ** This is neither the first nor the last request.
   2308              */
   2309         }
   2310         return Success;
   2311     }
   2312 }
   2313 
   2314 /************************************************************************/
   2315 
   2316 /*
   2317 ** No support is provided for the vendor-private requests other than
   2318 ** allocating the entry points in the dispatch table.
   2319 */
   2320 
   2321 int
   2322 __glXDisp_VendorPrivate(__GLXclientState * cl, GLbyte * pc)
   2323 {
   2324     ClientPtr client = cl->client;
   2325     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
   2326     GLint vendorcode = req->vendorCode;
   2327     __GLXdispatchVendorPrivProcPtr proc;
   2328 
   2329     REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
   2330 
   2331     proc = (__GLXdispatchVendorPrivProcPtr)
   2332         __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info,
   2333                                        vendorcode, 0);
   2334     if (proc != NULL) {
   2335         return (*proc) (cl, (GLbyte *) req);
   2336     }
   2337 
   2338     cl->client->errorValue = req->vendorCode;
   2339     return __glXError(GLXUnsupportedPrivateRequest);
   2340 }
   2341 
   2342 int
   2343 __glXDisp_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc)
   2344 {
   2345     ClientPtr client = cl->client;
   2346     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
   2347     GLint vendorcode = req->vendorCode;
   2348     __GLXdispatchVendorPrivProcPtr proc;
   2349 
   2350     REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
   2351 
   2352     proc = (__GLXdispatchVendorPrivProcPtr)
   2353         __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info,
   2354                                        vendorcode, 0);
   2355     if (proc != NULL) {
   2356         return (*proc) (cl, (GLbyte *) req);
   2357     }
   2358 
   2359     cl->client->errorValue = vendorcode;
   2360     return __glXError(GLXUnsupportedPrivateRequest);
   2361 }
   2362 
   2363 int
   2364 __glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc)
   2365 {
   2366     ClientPtr client = cl->client;
   2367     xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
   2368     xGLXQueryExtensionsStringReply reply;
   2369     __GLXscreen *pGlxScreen;
   2370     size_t n, length;
   2371     char *buf;
   2372     int err;
   2373 
   2374     if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
   2375         return err;
   2376 
   2377     n = strlen(pGlxScreen->GLXextensions) + 1;
   2378     length = __GLX_PAD(n) >> 2;
   2379     reply = (xGLXQueryExtensionsStringReply) {
   2380         .type = X_Reply,
   2381         .sequenceNumber = client->sequence,
   2382         .length = length,
   2383         .n = n
   2384     };
   2385 
   2386     /* Allocate buffer to make sure it's a multiple of 4 bytes big. */
   2387     buf = calloc(length, 4);
   2388     if (buf == NULL)
   2389         return BadAlloc;
   2390     memcpy(buf, pGlxScreen->GLXextensions, n);
   2391 
   2392     if (client->swapped) {
   2393         __GLX_DECLARE_SWAP_VARIABLES;
   2394         __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
   2395         __GLX_SWAP_SHORT(&reply.sequenceNumber);
   2396         __GLX_SWAP_INT(&reply.length);
   2397         __GLX_SWAP_INT(&reply.n);
   2398         WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply);
   2399         __GLX_SWAP_INT_ARRAY((int *) buf, length);
   2400         WriteToClient(client, length << 2, buf);
   2401     }
   2402     else {
   2403         WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply);
   2404         WriteToClient(client, (int) (length << 2), buf);
   2405     }
   2406 
   2407     free(buf);
   2408     return Success;
   2409 }
   2410 
   2411 #ifndef GLX_VENDOR_NAMES_EXT
   2412 #define GLX_VENDOR_NAMES_EXT 0x20F6
   2413 #endif
   2414 
   2415 int
   2416 __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
   2417 {
   2418     ClientPtr client = cl->client;
   2419     xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
   2420     xGLXQueryServerStringReply reply;
   2421     size_t n, length;
   2422     const char *ptr;
   2423     char *buf;
   2424     __GLXscreen *pGlxScreen;
   2425     int err;
   2426 
   2427     if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
   2428         return err;
   2429 
   2430     switch (req->name) {
   2431     case GLX_VENDOR:
   2432         ptr = GLXServerVendorName;
   2433         break;
   2434     case GLX_VERSION:
   2435         ptr = "1.4";
   2436         break;
   2437     case GLX_EXTENSIONS:
   2438         ptr = pGlxScreen->GLXextensions;
   2439         break;
   2440     case GLX_VENDOR_NAMES_EXT:
   2441         if (pGlxScreen->glvnd) {
   2442             ptr = pGlxScreen->glvnd;
   2443             break;
   2444         }
   2445         /* else fall through */
   2446     default:
   2447         return BadValue;
   2448     }
   2449 
   2450     n = strlen(ptr) + 1;
   2451     length = __GLX_PAD(n) >> 2;
   2452     reply = (xGLXQueryServerStringReply) {
   2453         .type = X_Reply,
   2454         .sequenceNumber = client->sequence,
   2455         .length = length,
   2456         .n = n
   2457     };
   2458 
   2459     buf = calloc(length, 4);
   2460     if (buf == NULL) {
   2461         return BadAlloc;
   2462     }
   2463     memcpy(buf, ptr, n);
   2464 
   2465     if (client->swapped) {
   2466         __GLX_DECLARE_SWAP_VARIABLES;
   2467         __GLX_SWAP_SHORT(&reply.sequenceNumber);
   2468         __GLX_SWAP_INT(&reply.length);
   2469         __GLX_SWAP_INT(&reply.n);
   2470         WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
   2471         /** no swap is needed for an array of chars **/
   2472         /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */
   2473         WriteToClient(client, length << 2, buf);
   2474     }
   2475     else {
   2476         WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
   2477         WriteToClient(client, (int) (length << 2), buf);
   2478     }
   2479 
   2480     free(buf);
   2481     return Success;
   2482 }
   2483 
   2484 int
   2485 __glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc)
   2486 {
   2487     ClientPtr client = cl->client;
   2488     xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
   2489     const char *buf;
   2490 
   2491     REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq);
   2492 
   2493     buf = (const char *) (req + 1);
   2494     if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq)))
   2495         return BadLength;
   2496 
   2497     free(cl->GLClientextensions);
   2498     cl->GLClientextensions = strdup(buf);
   2499 
   2500     return Success;
   2501 }
   2502 
   2503 #include <GL/glxtokens.h>
   2504 
   2505 void
   2506 __glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust,
   2507                    CARD64 msc, CARD32 sbc)
   2508 {
   2509     ClientPtr client = clients[CLIENT_ID(drawable->drawId)];
   2510 
   2511     xGLXBufferSwapComplete2 wire =  {
   2512         .type = __glXEventBase + GLX_BufferSwapComplete
   2513     };
   2514 
   2515     if (!client)
   2516         return;
   2517 
   2518     if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
   2519         return;
   2520 
   2521     wire.event_type = type;
   2522     wire.drawable = drawable->drawId;
   2523     wire.ust_hi = ust >> 32;
   2524     wire.ust_lo = ust & 0xffffffff;
   2525     wire.msc_hi = msc >> 32;
   2526     wire.msc_lo = msc & 0xffffffff;
   2527     wire.sbc = sbc;
   2528 
   2529     WriteEventsToClient(client, 1, (xEvent *) &wire);
   2530 }
   2531 
   2532 #if PRESENT
   2533 static void
   2534 __glXpresentCompleteNotify(WindowPtr window, CARD8 present_kind, CARD8 present_mode,
   2535                            CARD32 serial, uint64_t ust, uint64_t msc)
   2536 {
   2537     __GLXdrawable *drawable;
   2538     int glx_type;
   2539     int rc;
   2540 
   2541     if (present_kind != PresentCompleteKindPixmap)
   2542         return;
   2543 
   2544     rc = dixLookupResourceByType((void **) &drawable, window->drawable.id,
   2545                                  __glXDrawableRes, serverClient, DixGetAttrAccess);
   2546 
   2547     if (rc != Success)
   2548         return;
   2549 
   2550     if (present_mode == PresentCompleteModeFlip)
   2551         glx_type = GLX_FLIP_COMPLETE_INTEL;
   2552     else
   2553         glx_type = GLX_BLIT_COMPLETE_INTEL;
   2554 
   2555     __glXsendSwapEvent(drawable, glx_type, ust, msc, serial);
   2556 }
   2557 
   2558 #include <present.h>
   2559 
   2560 void
   2561 __glXregisterPresentCompleteNotify(void)
   2562 {
   2563     present_register_complete_notify(__glXpresentCompleteNotify);
   2564 }
   2565 #endif