Home | History | Annotate | Download | only in glx
      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 /**
     32  * \file glxcmds.c
     33  * Client-side GLX interface.
     34  */
     35 
     36 #include "glxclient.h"
     37 #include "glapi.h"
     38 #include "glxextensions.h"
     39 #include "indirect.h"
     40 #include "glx_error.h"
     41 
     42 #ifdef GLX_DIRECT_RENDERING
     43 #ifdef GLX_USE_APPLEGL
     44 #include "apple/apple_glx_context.h"
     45 #include "apple/apple_glx.h"
     46 #include "util/debug.h"
     47 #else
     48 #include <sys/time.h>
     49 #ifdef XF86VIDMODE
     50 #include <X11/extensions/xf86vmode.h>
     51 #endif
     52 #endif
     53 #endif
     54 
     55 #include <X11/Xlib-xcb.h>
     56 #include <xcb/xcb.h>
     57 #include <xcb/glx.h>
     58 #include "GL/mesa_glinterop.h"
     59 
     60 static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
     61 static const char __glXGLXClientVersion[] = "1.4";
     62 
     63 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
     64 
     65 /**
     66  * Get the __DRIdrawable for the drawable associated with a GLXContext
     67  *
     68  * \param dpy       The display associated with \c drawable.
     69  * \param drawable  GLXDrawable whose __DRIdrawable part is to be retrieved.
     70  * \param scrn_num  If non-NULL, the drawables screen is stored there
     71  * \returns  A pointer to the context's __DRIdrawable on success, or NULL if
     72  *           the drawable is not associated with a direct-rendering context.
     73  */
     74 _X_HIDDEN __GLXDRIdrawable *
     75 GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable)
     76 {
     77    struct glx_display *priv = __glXInitialize(dpy);
     78    __GLXDRIdrawable *pdraw;
     79 
     80    if (priv == NULL)
     81       return NULL;
     82 
     83    if (__glxHashLookup(priv->drawHash, drawable, (void *) &pdraw) == 0)
     84       return pdraw;
     85 
     86    return NULL;
     87 }
     88 
     89 #endif
     90 
     91 _X_HIDDEN struct glx_drawable *
     92 GetGLXDrawable(Display *dpy, GLXDrawable drawable)
     93 {
     94    struct glx_display *priv = __glXInitialize(dpy);
     95    struct glx_drawable *glxDraw;
     96 
     97    if (priv == NULL)
     98       return NULL;
     99 
    100    if (__glxHashLookup(priv->glXDrawHash, drawable, (void *) &glxDraw) == 0)
    101       return glxDraw;
    102 
    103    return NULL;
    104 }
    105 
    106 _X_HIDDEN int
    107 InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable,
    108 		GLXDrawable drawable)
    109 {
    110    struct glx_display *priv = __glXInitialize(dpy);
    111 
    112    if (!priv)
    113       return -1;
    114 
    115    glxDraw->xDrawable = xDrawable;
    116    glxDraw->drawable = drawable;
    117    glxDraw->lastEventSbc = 0;
    118    glxDraw->eventSbcWrap = 0;
    119 
    120    return __glxHashInsert(priv->glXDrawHash, drawable, glxDraw);
    121 }
    122 
    123 _X_HIDDEN void
    124 DestroyGLXDrawable(Display *dpy, GLXDrawable drawable)
    125 {
    126    struct glx_display *priv = __glXInitialize(dpy);
    127    struct glx_drawable *glxDraw;
    128 
    129    if (!priv)
    130       return;
    131 
    132    glxDraw = GetGLXDrawable(dpy, drawable);
    133    __glxHashDelete(priv->glXDrawHash, drawable);
    134    free(glxDraw);
    135 }
    136 
    137 /**
    138  * Get the GLX per-screen data structure associated with a GLX context.
    139  *
    140  * \param dpy   Display for which the GLX per-screen information is to be
    141  *              retrieved.
    142  * \param scrn  Screen on \c dpy for which the GLX per-screen information is
    143  *              to be retrieved.
    144  * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn
    145  *          specify a valid GLX screen, or NULL otherwise.
    146  *
    147  * \todo Should this function validate that \c scrn is within the screen
    148  *       number range for \c dpy?
    149  */
    150 
    151 _X_HIDDEN struct glx_screen *
    152 GetGLXScreenConfigs(Display * dpy, int scrn)
    153 {
    154    struct glx_display *const priv = __glXInitialize(dpy);
    155 
    156    return (priv
    157            && priv->screens !=
    158            NULL) ? priv->screens[scrn] : NULL;
    159 }
    160 
    161 
    162 static int
    163 GetGLXPrivScreenConfig(Display * dpy, int scrn, struct glx_display ** ppriv,
    164                        struct glx_screen ** ppsc)
    165 {
    166    /* Initialize the extension, if needed .  This has the added value
    167     * of initializing/allocating the display private
    168     */
    169 
    170    if (dpy == NULL) {
    171       return GLX_NO_EXTENSION;
    172    }
    173 
    174    *ppriv = __glXInitialize(dpy);
    175    if (*ppriv == NULL) {
    176       return GLX_NO_EXTENSION;
    177    }
    178 
    179    /* Check screen number to see if its valid */
    180    if ((scrn < 0) || (scrn >= ScreenCount(dpy))) {
    181       return GLX_BAD_SCREEN;
    182    }
    183 
    184    /* Check to see if the GL is supported on this screen */
    185    *ppsc = (*ppriv)->screens[scrn];
    186    if ((*ppsc)->configs == NULL && (*ppsc)->visuals == NULL) {
    187       /* No support for GL on this screen regardless of visual */
    188       return GLX_BAD_VISUAL;
    189    }
    190 
    191    return Success;
    192 }
    193 
    194 
    195 /**
    196  * Determine if a \c GLXFBConfig supplied by the application is valid.
    197  *
    198  * \param dpy     Application supplied \c Display pointer.
    199  * \param config  Application supplied \c GLXFBConfig.
    200  *
    201  * \returns If the \c GLXFBConfig is valid, the a pointer to the matching
    202  *          \c struct glx_config structure is returned.  Otherwise, \c NULL
    203  *          is returned.
    204  */
    205 static struct glx_config *
    206 ValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig)
    207 {
    208    struct glx_display *const priv = __glXInitialize(dpy);
    209    int num_screens = ScreenCount(dpy);
    210    unsigned i;
    211    struct glx_config *config;
    212 
    213    if (priv != NULL) {
    214       for (i = 0; i < num_screens; i++) {
    215 	 for (config = priv->screens[i]->configs; config != NULL;
    216 	      config = config->next) {
    217 	    if (config == (struct glx_config *) fbconfig) {
    218 	       return config;
    219 	    }
    220 	 }
    221       }
    222    }
    223 
    224    return NULL;
    225 }
    226 
    227 /**
    228  * Verifies context's GLX_RENDER_TYPE value with config.
    229  *
    230  * \param config GLX FBConfig which will support the returned renderType.
    231  * \param renderType The context render type to be verified.
    232  * \return True if the value of context renderType was approved, or 0 if no
    233  * valid value was found.
    234  */
    235 Bool
    236 validate_renderType_against_config(const struct glx_config *config,
    237                                    int renderType)
    238 {
    239    /* GLX_EXT_no_config_context supports any render type */
    240    if (!config)
    241       return True;
    242 
    243    switch (renderType) {
    244       case GLX_RGBA_TYPE:
    245          return (config->renderType & GLX_RGBA_BIT) != 0;
    246       case GLX_COLOR_INDEX_TYPE:
    247          return (config->renderType & GLX_COLOR_INDEX_BIT) != 0;
    248       case GLX_RGBA_FLOAT_TYPE_ARB:
    249          return (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) != 0;
    250       case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT:
    251          return (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) != 0;
    252       default:
    253          break;
    254    }
    255    return 0;
    256 }
    257 
    258 _X_HIDDEN Bool
    259 glx_context_init(struct glx_context *gc,
    260 		 struct glx_screen *psc, struct glx_config *config)
    261 {
    262    gc->majorOpcode = __glXSetupForCommand(psc->display->dpy);
    263    if (!gc->majorOpcode)
    264       return False;
    265 
    266    gc->screen = psc->scr;
    267    gc->psc = psc;
    268    gc->config = config;
    269    gc->isDirect = GL_TRUE;
    270    gc->currentContextTag = -1;
    271 
    272    return True;
    273 }
    274 
    275 
    276 /**
    277  * Create a new context.
    278  *
    279  * \param renderType   For FBConfigs, what is the rendering type?
    280  */
    281 
    282 static GLXContext
    283 CreateContext(Display *dpy, int generic_id, struct glx_config *config,
    284               GLXContext shareList_user, Bool allowDirect,
    285 	      unsigned code, int renderType, int screen)
    286 {
    287    struct glx_context *gc;
    288    struct glx_screen *psc;
    289    struct glx_context *shareList = (struct glx_context *) shareList_user;
    290    if (dpy == NULL)
    291       return NULL;
    292 
    293    psc = GetGLXScreenConfigs(dpy, screen);
    294    if (psc == NULL)
    295       return NULL;
    296 
    297    if (generic_id == None)
    298       return NULL;
    299 
    300    gc = NULL;
    301 #ifdef GLX_USE_APPLEGL
    302    gc = applegl_create_context(psc, config, shareList, renderType);
    303 #else
    304    if (allowDirect && psc->vtable->create_context)
    305       gc = psc->vtable->create_context(psc, config, shareList, renderType);
    306    if (!gc)
    307       gc = indirect_create_context(psc, config, shareList, renderType);
    308 #endif
    309    if (!gc)
    310       return NULL;
    311 
    312    LockDisplay(dpy);
    313    switch (code) {
    314    case X_GLXCreateContext: {
    315       xGLXCreateContextReq *req;
    316 
    317       /* Send the glXCreateContext request */
    318       GetReq(GLXCreateContext, req);
    319       req->reqType = gc->majorOpcode;
    320       req->glxCode = X_GLXCreateContext;
    321       req->context = gc->xid = XAllocID(dpy);
    322       req->visual = generic_id;
    323       req->screen = screen;
    324       req->shareList = shareList ? shareList->xid : None;
    325       req->isDirect = gc->isDirect;
    326       break;
    327    }
    328 
    329    case X_GLXCreateNewContext: {
    330       xGLXCreateNewContextReq *req;
    331 
    332       /* Send the glXCreateNewContext request */
    333       GetReq(GLXCreateNewContext, req);
    334       req->reqType = gc->majorOpcode;
    335       req->glxCode = X_GLXCreateNewContext;
    336       req->context = gc->xid = XAllocID(dpy);
    337       req->fbconfig = generic_id;
    338       req->screen = screen;
    339       req->renderType = renderType;
    340       req->shareList = shareList ? shareList->xid : None;
    341       req->isDirect = gc->isDirect;
    342       break;
    343    }
    344 
    345    case X_GLXvop_CreateContextWithConfigSGIX: {
    346       xGLXVendorPrivateWithReplyReq *vpreq;
    347       xGLXCreateContextWithConfigSGIXReq *req;
    348 
    349       /* Send the glXCreateNewContext request */
    350       GetReqExtra(GLXVendorPrivateWithReply,
    351 		  sz_xGLXCreateContextWithConfigSGIXReq -
    352 		  sz_xGLXVendorPrivateWithReplyReq, vpreq);
    353       req = (xGLXCreateContextWithConfigSGIXReq *) vpreq;
    354       req->reqType = gc->majorOpcode;
    355       req->glxCode = X_GLXVendorPrivateWithReply;
    356       req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
    357       req->context = gc->xid = XAllocID(dpy);
    358       req->fbconfig = generic_id;
    359       req->screen = screen;
    360       req->renderType = renderType;
    361       req->shareList = shareList ? shareList->xid : None;
    362       req->isDirect = gc->isDirect;
    363       break;
    364    }
    365 
    366    default:
    367       /* What to do here?  This case is the sign of an internal error.  It
    368        * should never be reachable.
    369        */
    370       break;
    371    }
    372 
    373    UnlockDisplay(dpy);
    374    SyncHandle();
    375 
    376    gc->share_xid = shareList ? shareList->xid : None;
    377    gc->imported = GL_FALSE;
    378 
    379    return (GLXContext) gc;
    380 }
    381 
    382 _GLX_PUBLIC GLXContext
    383 glXCreateContext(Display * dpy, XVisualInfo * vis,
    384                  GLXContext shareList, Bool allowDirect)
    385 {
    386    struct glx_config *config = NULL;
    387    int renderType = GLX_RGBA_TYPE;
    388 
    389 #if defined(GLX_DIRECT_RENDERING) || defined(GLX_USE_APPLEGL)
    390    struct glx_screen *const psc = GetGLXScreenConfigs(dpy, vis->screen);
    391 
    392    if (psc)
    393       config = glx_config_find_visual(psc->visuals, vis->visualid);
    394 
    395    if (config == NULL) {
    396       __glXSendError(dpy, BadValue, vis->visualid, X_GLXCreateContext, True);
    397       return None;
    398    }
    399 
    400    /* Choose the context render type based on DRI config values.  It is
    401     * unusual to set this type from config, but we have no other choice, as
    402     * this old API does not provide renderType parameter.
    403     */
    404    if (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) {
    405        renderType = GLX_RGBA_FLOAT_TYPE_ARB;
    406    } else if (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) {
    407        renderType = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT;
    408    } else if (config->renderType & GLX_RGBA_BIT) {
    409        renderType = GLX_RGBA_TYPE;
    410    } else if (config->renderType & GLX_COLOR_INDEX_BIT) {
    411        renderType = GLX_COLOR_INDEX_TYPE;
    412    } else if (config->rgbMode) {
    413        /* If we're here, then renderType is not set correctly.  Let's use a
    414         * safeguard - any TrueColor or DirectColor mode is RGB mode.  Such
    415         * default value is needed by old DRI drivers, which didn't set
    416         * renderType correctly as the value was just ignored.
    417         */
    418        renderType = GLX_RGBA_TYPE;
    419    } else {
    420        /* Safeguard - only one option left, all non-RGB modes are indexed
    421         * modes.  Again, this allows drivers with invalid renderType to work
    422         * properly.
    423         */
    424        renderType = GLX_COLOR_INDEX_TYPE;
    425    }
    426 #endif
    427 
    428    return CreateContext(dpy, vis->visualid, config, shareList, allowDirect,
    429                         X_GLXCreateContext, renderType, vis->screen);
    430 }
    431 
    432 static void
    433 glx_send_destroy_context(Display *dpy, XID xid)
    434 {
    435    CARD8 opcode = __glXSetupForCommand(dpy);
    436    xGLXDestroyContextReq *req;
    437 
    438    LockDisplay(dpy);
    439    GetReq(GLXDestroyContext, req);
    440    req->reqType = opcode;
    441    req->glxCode = X_GLXDestroyContext;
    442    req->context = xid;
    443    UnlockDisplay(dpy);
    444    SyncHandle();
    445 }
    446 
    447 /*
    448 ** Destroy the named context
    449 */
    450 
    451 _GLX_PUBLIC void
    452 glXDestroyContext(Display * dpy, GLXContext ctx)
    453 {
    454    struct glx_context *gc = (struct glx_context *) ctx;
    455 
    456    if (gc == NULL || gc->xid == None)
    457       return;
    458 
    459    __glXLock();
    460    if (!gc->imported)
    461       glx_send_destroy_context(dpy, gc->xid);
    462 
    463    if (gc->currentDpy) {
    464       /* This context is bound to some thread.  According to the man page,
    465        * we should not actually delete the context until it's unbound.
    466        * Note that we set gc->xid = None above.  In MakeContextCurrent()
    467        * we check for that and delete the context there.
    468        */
    469       gc->xid = None;
    470    } else {
    471       gc->vtable->destroy(gc);
    472    }
    473    __glXUnlock();
    474 }
    475 
    476 /*
    477 ** Return the major and minor version #s for the GLX extension
    478 */
    479 _GLX_PUBLIC Bool
    480 glXQueryVersion(Display * dpy, int *major, int *minor)
    481 {
    482    struct glx_display *priv;
    483 
    484    /* Init the extension.  This fetches the major and minor version. */
    485    priv = __glXInitialize(dpy);
    486    if (!priv)
    487       return False;
    488 
    489    if (major)
    490       *major = priv->majorVersion;
    491    if (minor)
    492       *minor = priv->minorVersion;
    493    return True;
    494 }
    495 
    496 /*
    497 ** Query the existence of the GLX extension
    498 */
    499 _GLX_PUBLIC Bool
    500 glXQueryExtension(Display * dpy, int *errorBase, int *eventBase)
    501 {
    502    int major_op, erb, evb;
    503    Bool rv;
    504 
    505    rv = XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_op, &evb, &erb);
    506    if (rv) {
    507       if (errorBase)
    508          *errorBase = erb;
    509       if (eventBase)
    510          *eventBase = evb;
    511    }
    512    return rv;
    513 }
    514 
    515 /*
    516 ** Put a barrier in the token stream that forces the GL to finish its
    517 ** work before X can proceed.
    518 */
    519 _GLX_PUBLIC void
    520 glXWaitGL(void)
    521 {
    522    struct glx_context *gc = __glXGetCurrentContext();
    523 
    524    if (gc->vtable->wait_gl)
    525       gc->vtable->wait_gl(gc);
    526 }
    527 
    528 /*
    529 ** Put a barrier in the token stream that forces X to finish its
    530 ** work before GL can proceed.
    531 */
    532 _GLX_PUBLIC void
    533 glXWaitX(void)
    534 {
    535    struct glx_context *gc = __glXGetCurrentContext();
    536 
    537    if (gc->vtable->wait_x)
    538       gc->vtable->wait_x(gc);
    539 }
    540 
    541 _GLX_PUBLIC void
    542 glXUseXFont(Font font, int first, int count, int listBase)
    543 {
    544    struct glx_context *gc = __glXGetCurrentContext();
    545 
    546    if (gc->vtable->use_x_font)
    547       gc->vtable->use_x_font(gc, font, first, count, listBase);
    548 }
    549 
    550 /************************************************************************/
    551 
    552 /*
    553 ** Copy the source context to the destination context using the
    554 ** attribute "mask".
    555 */
    556 _GLX_PUBLIC void
    557 glXCopyContext(Display * dpy, GLXContext source_user,
    558 	       GLXContext dest_user, unsigned long mask)
    559 {
    560    struct glx_context *source = (struct glx_context *) source_user;
    561    struct glx_context *dest = (struct glx_context *) dest_user;
    562 #ifdef GLX_USE_APPLEGL
    563    struct glx_context *gc = __glXGetCurrentContext();
    564    int errorcode;
    565    bool x11error;
    566 
    567    if(apple_glx_copy_context(gc->driContext, source->driContext, dest->driContext,
    568                              mask, &errorcode, &x11error)) {
    569       __glXSendError(dpy, errorcode, 0, X_GLXCopyContext, x11error);
    570    }
    571 
    572 #else
    573    xGLXCopyContextReq *req;
    574    struct glx_context *gc = __glXGetCurrentContext();
    575    GLXContextTag tag;
    576    CARD8 opcode;
    577 
    578    opcode = __glXSetupForCommand(dpy);
    579    if (!opcode) {
    580       return;
    581    }
    582 
    583 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    584    if (gc->isDirect) {
    585       /* NOT_DONE: This does not work yet */
    586    }
    587 #endif
    588 
    589    /*
    590     ** If the source is the current context, send its tag so that the context
    591     ** can be flushed before the copy.
    592     */
    593    if (source == gc && dpy == gc->currentDpy) {
    594       tag = gc->currentContextTag;
    595    }
    596    else {
    597       tag = 0;
    598    }
    599 
    600    /* Send the glXCopyContext request */
    601    LockDisplay(dpy);
    602    GetReq(GLXCopyContext, req);
    603    req->reqType = opcode;
    604    req->glxCode = X_GLXCopyContext;
    605    req->source = source ? source->xid : None;
    606    req->dest = dest ? dest->xid : None;
    607    req->mask = mask;
    608    req->contextTag = tag;
    609    UnlockDisplay(dpy);
    610    SyncHandle();
    611 #endif /* GLX_USE_APPLEGL */
    612 }
    613 
    614 
    615 /**
    616  * Determine if a context uses direct rendering.
    617  *
    618  * \param dpy        Display where the context was created.
    619  * \param contextID  ID of the context to be tested.
    620  *
    621  * \returns \c True if the context is direct rendering or not.
    622  */
    623 static Bool
    624 __glXIsDirect(Display * dpy, GLXContextID contextID)
    625 {
    626    CARD8 opcode;
    627    xcb_connection_t *c;
    628    xcb_generic_error_t *err;
    629    xcb_glx_is_direct_reply_t *reply;
    630    Bool is_direct;
    631 
    632    opcode = __glXSetupForCommand(dpy);
    633    if (!opcode) {
    634       return False;
    635    }
    636 
    637    c = XGetXCBConnection(dpy);
    638    reply = xcb_glx_is_direct_reply(c, xcb_glx_is_direct(c, contextID), &err);
    639    is_direct = (reply != NULL && reply->is_direct) ? True : False;
    640 
    641    if (err != NULL) {
    642       __glXSendErrorForXcb(dpy, err);
    643       free(err);
    644    }
    645 
    646    free(reply);
    647 
    648    return is_direct;
    649 }
    650 
    651 /**
    652  * \todo
    653  * Shouldn't this function \b always return \c False when
    654  * \c GLX_DIRECT_RENDERING is not defined?  Do we really need to bother with
    655  * the GLX protocol here at all?
    656  */
    657 _GLX_PUBLIC Bool
    658 glXIsDirect(Display * dpy, GLXContext gc_user)
    659 {
    660    struct glx_context *gc = (struct glx_context *) gc_user;
    661 
    662    if (!gc) {
    663       return False;
    664    }
    665    else if (gc->isDirect) {
    666       return True;
    667    }
    668 #ifdef GLX_USE_APPLEGL  /* TODO: indirect on darwin */
    669    return False;
    670 #else
    671    return __glXIsDirect(dpy, gc->xid);
    672 #endif
    673 }
    674 
    675 _GLX_PUBLIC GLXPixmap
    676 glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
    677 {
    678 #ifdef GLX_USE_APPLEGL
    679    int screen = vis->screen;
    680    struct glx_screen *const psc = GetGLXScreenConfigs(dpy, screen);
    681    const struct glx_config *config;
    682 
    683    config = glx_config_find_visual(psc->visuals, vis->visualid);
    684 
    685    if(apple_glx_pixmap_create(dpy, vis->screen, pixmap, config))
    686       return None;
    687 
    688    return pixmap;
    689 #else
    690    xGLXCreateGLXPixmapReq *req;
    691    struct glx_drawable *glxDraw;
    692    GLXPixmap xid;
    693    CARD8 opcode;
    694 
    695 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    696    struct glx_display *const priv = __glXInitialize(dpy);
    697 
    698    if (priv == NULL)
    699       return None;
    700 #endif
    701 
    702    opcode = __glXSetupForCommand(dpy);
    703    if (!opcode) {
    704       return None;
    705    }
    706 
    707    glxDraw = malloc(sizeof(*glxDraw));
    708    if (!glxDraw)
    709       return None;
    710 
    711    /* Send the glXCreateGLXPixmap request */
    712    LockDisplay(dpy);
    713    GetReq(GLXCreateGLXPixmap, req);
    714    req->reqType = opcode;
    715    req->glxCode = X_GLXCreateGLXPixmap;
    716    req->screen = vis->screen;
    717    req->visual = vis->visualid;
    718    req->pixmap = pixmap;
    719    req->glxpixmap = xid = XAllocID(dpy);
    720    UnlockDisplay(dpy);
    721    SyncHandle();
    722 
    723    if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) {
    724       free(glxDraw);
    725       return None;
    726    }
    727 
    728 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    729    do {
    730       /* FIXME: Maybe delay __DRIdrawable creation until the drawable
    731        * is actually bound to a context... */
    732 
    733       __GLXDRIdrawable *pdraw;
    734       struct glx_screen *psc;
    735       struct glx_config *config;
    736 
    737       psc = priv->screens[vis->screen];
    738       if (psc->driScreen == NULL)
    739          return xid;
    740 
    741       config = glx_config_find_visual(psc->visuals, vis->visualid);
    742       pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config);
    743       if (pdraw == NULL) {
    744          fprintf(stderr, "failed to create pixmap\n");
    745          xid = None;
    746          break;
    747       }
    748 
    749       if (__glxHashInsert(priv->drawHash, xid, pdraw)) {
    750          (*pdraw->destroyDrawable) (pdraw);
    751          xid = None;
    752          break;
    753       }
    754    } while (0);
    755 
    756    if (xid == None) {
    757       xGLXDestroyGLXPixmapReq *dreq;
    758       LockDisplay(dpy);
    759       GetReq(GLXDestroyGLXPixmap, dreq);
    760       dreq->reqType = opcode;
    761       dreq->glxCode = X_GLXDestroyGLXPixmap;
    762       dreq->glxpixmap = xid;
    763       UnlockDisplay(dpy);
    764       SyncHandle();
    765    }
    766 #endif
    767 
    768    return xid;
    769 #endif
    770 }
    771 
    772 /*
    773 ** Destroy the named pixmap
    774 */
    775 _GLX_PUBLIC void
    776 glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
    777 {
    778 #ifdef GLX_USE_APPLEGL
    779    if(apple_glx_pixmap_destroy(dpy, glxpixmap))
    780       __glXSendError(dpy, GLXBadPixmap, glxpixmap, X_GLXDestroyPixmap, false);
    781 #else
    782    xGLXDestroyGLXPixmapReq *req;
    783    CARD8 opcode;
    784 
    785    opcode = __glXSetupForCommand(dpy);
    786    if (!opcode) {
    787       return;
    788    }
    789 
    790    /* Send the glXDestroyGLXPixmap request */
    791    LockDisplay(dpy);
    792    GetReq(GLXDestroyGLXPixmap, req);
    793    req->reqType = opcode;
    794    req->glxCode = X_GLXDestroyGLXPixmap;
    795    req->glxpixmap = glxpixmap;
    796    UnlockDisplay(dpy);
    797    SyncHandle();
    798 
    799    DestroyGLXDrawable(dpy, glxpixmap);
    800 
    801 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    802    {
    803       struct glx_display *const priv = __glXInitialize(dpy);
    804       __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap);
    805 
    806       if (priv != NULL && pdraw != NULL) {
    807          (*pdraw->destroyDrawable) (pdraw);
    808          __glxHashDelete(priv->drawHash, glxpixmap);
    809       }
    810    }
    811 #endif
    812 #endif /* GLX_USE_APPLEGL */
    813 }
    814 
    815 _GLX_PUBLIC void
    816 glXSwapBuffers(Display * dpy, GLXDrawable drawable)
    817 {
    818 #ifdef GLX_USE_APPLEGL
    819    struct glx_context * gc = __glXGetCurrentContext();
    820    if(gc != &dummyContext && apple_glx_is_current_drawable(dpy, gc->driContext, drawable)) {
    821       apple_glx_swap_buffers(gc->driContext);
    822    } else {
    823       __glXSendError(dpy, GLXBadCurrentWindow, 0, X_GLXSwapBuffers, false);
    824    }
    825 #else
    826    struct glx_context *gc;
    827    GLXContextTag tag;
    828    CARD8 opcode;
    829    xcb_connection_t *c;
    830 
    831    gc = __glXGetCurrentContext();
    832 
    833 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    834    {
    835       __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
    836 
    837       if (pdraw != NULL) {
    838          Bool flush = gc != &dummyContext && drawable == gc->currentDrawable;
    839 
    840          (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0, flush);
    841          return;
    842       }
    843    }
    844 #endif
    845 
    846    opcode = __glXSetupForCommand(dpy);
    847    if (!opcode) {
    848       return;
    849    }
    850 
    851    /*
    852     ** The calling thread may or may not have a current context.  If it
    853     ** does, send the context tag so the server can do a flush.
    854     */
    855    if ((gc != &dummyContext) && (dpy == gc->currentDpy) &&
    856        ((drawable == gc->currentDrawable)
    857         || (drawable == gc->currentReadable))) {
    858       tag = gc->currentContextTag;
    859    }
    860    else {
    861       tag = 0;
    862    }
    863 
    864    c = XGetXCBConnection(dpy);
    865    xcb_glx_swap_buffers(c, tag, drawable);
    866    xcb_flush(c);
    867 #endif /* GLX_USE_APPLEGL */
    868 }
    869 
    870 
    871 /*
    872 ** Return configuration information for the given display, screen and
    873 ** visual combination.
    874 */
    875 _GLX_PUBLIC int
    876 glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute,
    877              int *value_return)
    878 {
    879    struct glx_display *priv;
    880    struct glx_screen *psc;
    881    struct glx_config *config;
    882    int status;
    883 
    884    status = GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc);
    885    if (status == Success) {
    886       config = glx_config_find_visual(psc->visuals, vis->visualid);
    887 
    888       /* Lookup attribute after first finding a match on the visual */
    889       if (config != NULL) {
    890 	 return glx_config_get(config, attribute, value_return);
    891       }
    892 
    893       status = GLX_BAD_VISUAL;
    894    }
    895 
    896    /*
    897     ** If we can't find the config for this visual, this visual is not
    898     ** supported by the OpenGL implementation on the server.
    899     */
    900    if ((status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL)) {
    901       *value_return = False;
    902       status = Success;
    903    }
    904 
    905    return status;
    906 }
    907 
    908 /************************************************************************/
    909 
    910 static void
    911 init_fbconfig_for_chooser(struct glx_config * config,
    912                           GLboolean fbconfig_style_tags)
    913 {
    914    memset(config, 0, sizeof(struct glx_config));
    915    config->visualID = (XID) GLX_DONT_CARE;
    916    config->visualType = GLX_DONT_CARE;
    917 
    918    /* glXChooseFBConfig specifies different defaults for these properties than
    919     * glXChooseVisual.
    920     */
    921    if (fbconfig_style_tags) {
    922       config->rgbMode = GL_TRUE;
    923       config->doubleBufferMode = GLX_DONT_CARE;
    924       config->renderType = GLX_RGBA_BIT;
    925    }
    926 
    927    config->drawableType = GLX_WINDOW_BIT;
    928    config->visualRating = GLX_DONT_CARE;
    929    config->transparentPixel = GLX_NONE;
    930    config->transparentRed = GLX_DONT_CARE;
    931    config->transparentGreen = GLX_DONT_CARE;
    932    config->transparentBlue = GLX_DONT_CARE;
    933    config->transparentAlpha = GLX_DONT_CARE;
    934    config->transparentIndex = GLX_DONT_CARE;
    935 
    936    config->xRenderable = GLX_DONT_CARE;
    937    config->fbconfigID = (GLXFBConfigID) (GLX_DONT_CARE);
    938 
    939    config->swapMethod = GLX_DONT_CARE;
    940 }
    941 
    942 #define MATCH_DONT_CARE( param )        \
    943   do {                                  \
    944     if ( ((int) a-> param != (int) GLX_DONT_CARE)   \
    945          && (a-> param != b-> param) ) {        \
    946       return False;                             \
    947     }                                           \
    948   } while ( 0 )
    949 
    950 #define MATCH_MINIMUM( param )                  \
    951   do {                                          \
    952     if ( ((int) a-> param != (int) GLX_DONT_CARE)	\
    953          && (a-> param > b-> param) ) {         \
    954       return False;                             \
    955     }                                           \
    956   } while ( 0 )
    957 
    958 #define MATCH_EXACT( param )                    \
    959   do {                                          \
    960     if ( a-> param != b-> param) {              \
    961       return False;                             \
    962     }                                           \
    963   } while ( 0 )
    964 
    965 /* Test that all bits from a are contained in b */
    966 #define MATCH_MASK(param)			\
    967   do {						\
    968     if ( ((int) a-> param != (int) GLX_DONT_CARE)	\
    969          && ((a->param & ~b->param) != 0) ) {   \
    970       return False;				\
    971     }                                           \
    972   } while (0);
    973 
    974 /**
    975  * Determine if two GLXFBConfigs are compatible.
    976  *
    977  * \param a  Application specified config to test.
    978  * \param b  Server specified config to test against \c a.
    979  */
    980 static Bool
    981 fbconfigs_compatible(const struct glx_config * const a,
    982                      const struct glx_config * const b)
    983 {
    984    MATCH_DONT_CARE(doubleBufferMode);
    985    MATCH_DONT_CARE(visualType);
    986    MATCH_DONT_CARE(visualRating);
    987    MATCH_DONT_CARE(xRenderable);
    988    MATCH_DONT_CARE(fbconfigID);
    989    MATCH_DONT_CARE(swapMethod);
    990 
    991    MATCH_MINIMUM(rgbBits);
    992    MATCH_MINIMUM(numAuxBuffers);
    993    MATCH_MINIMUM(redBits);
    994    MATCH_MINIMUM(greenBits);
    995    MATCH_MINIMUM(blueBits);
    996    MATCH_MINIMUM(alphaBits);
    997    MATCH_MINIMUM(depthBits);
    998    MATCH_MINIMUM(stencilBits);
    999    MATCH_MINIMUM(accumRedBits);
   1000    MATCH_MINIMUM(accumGreenBits);
   1001    MATCH_MINIMUM(accumBlueBits);
   1002    MATCH_MINIMUM(accumAlphaBits);
   1003    MATCH_MINIMUM(sampleBuffers);
   1004    MATCH_MINIMUM(maxPbufferWidth);
   1005    MATCH_MINIMUM(maxPbufferHeight);
   1006    MATCH_MINIMUM(maxPbufferPixels);
   1007    MATCH_MINIMUM(samples);
   1008 
   1009    MATCH_DONT_CARE(stereoMode);
   1010    MATCH_EXACT(level);
   1011 
   1012    MATCH_MASK(drawableType);
   1013    MATCH_MASK(renderType);
   1014    MATCH_DONT_CARE(sRGBCapable);
   1015 
   1016    /* There is a bug in a few of the XFree86 DDX drivers.  They contain
   1017     * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
   1018     * Technically speaking, it is a bug in the DDX driver, but there is
   1019     * enough of an installed base to work around the problem here.  In any
   1020     * case, 0 is not a valid value of the transparent type, so we'll treat 0
   1021     * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
   1022     * 0 from the server to be a match to maintain backward compatibility with
   1023     * the (broken) drivers.
   1024     */
   1025 
   1026    if (a->transparentPixel != (int) GLX_DONT_CARE && a->transparentPixel != 0) {
   1027       if (a->transparentPixel == GLX_NONE) {
   1028          if (b->transparentPixel != GLX_NONE && b->transparentPixel != 0)
   1029             return False;
   1030       }
   1031       else {
   1032          MATCH_EXACT(transparentPixel);
   1033       }
   1034 
   1035       switch (a->transparentPixel) {
   1036       case GLX_TRANSPARENT_RGB:
   1037          MATCH_DONT_CARE(transparentRed);
   1038          MATCH_DONT_CARE(transparentGreen);
   1039          MATCH_DONT_CARE(transparentBlue);
   1040          MATCH_DONT_CARE(transparentAlpha);
   1041          break;
   1042 
   1043       case GLX_TRANSPARENT_INDEX:
   1044          MATCH_DONT_CARE(transparentIndex);
   1045          break;
   1046 
   1047       default:
   1048          break;
   1049       }
   1050    }
   1051 
   1052    return True;
   1053 }
   1054 
   1055 
   1056 /* There's some trickly language in the GLX spec about how this is supposed
   1057  * to work.  Basically, if a given component size is either not specified
   1058  * or the requested size is zero, it is supposed to act like PERFER_SMALLER.
   1059  * Well, that's really hard to do with the code as-is.  This behavior is
   1060  * closer to correct, but still not technically right.
   1061  */
   1062 #define PREFER_LARGER_OR_ZERO(comp)             \
   1063   do {                                          \
   1064     if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
   1065       if ( ((*a)-> comp) == 0 ) {               \
   1066         return -1;                              \
   1067       }                                         \
   1068       else if ( ((*b)-> comp) == 0 ) {          \
   1069         return 1;                               \
   1070       }                                         \
   1071       else {                                    \
   1072         return ((*b)-> comp) - ((*a)-> comp) ;  \
   1073       }                                         \
   1074     }                                           \
   1075   } while( 0 )
   1076 
   1077 #define PREFER_LARGER(comp)                     \
   1078   do {                                          \
   1079     if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
   1080       return ((*b)-> comp) - ((*a)-> comp) ;    \
   1081     }                                           \
   1082   } while( 0 )
   1083 
   1084 #define PREFER_SMALLER(comp)                    \
   1085   do {                                          \
   1086     if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
   1087       return ((*a)-> comp) - ((*b)-> comp) ;    \
   1088     }                                           \
   1089   } while( 0 )
   1090 
   1091 /**
   1092  * Compare two GLXFBConfigs.  This function is intended to be used as the
   1093  * compare function passed in to qsort.
   1094  *
   1095  * \returns If \c a is a "better" config, according to the specification of
   1096  *          SGIX_fbconfig, a number less than zero is returned.  If \c b is
   1097  *          better, then a number greater than zero is return.  If both are
   1098  *          equal, zero is returned.
   1099  * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
   1100  */
   1101 static int
   1102 fbconfig_compare(struct glx_config **a, struct glx_config **b)
   1103 {
   1104    /* The order of these comparisons must NOT change.  It is defined by
   1105     * the GLX 1.4 specification.
   1106     */
   1107 
   1108    PREFER_SMALLER(visualSelectGroup);
   1109 
   1110    /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
   1111     * GLX_NON_CONFORMANT_CONFIG.  It just so happens that this is the
   1112     * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
   1113     */
   1114    PREFER_SMALLER(visualRating);
   1115 
   1116    /* This isn't quite right.  It is supposed to compare the sum of the
   1117     * components the user specifically set minimums for.
   1118     */
   1119    PREFER_LARGER_OR_ZERO(redBits);
   1120    PREFER_LARGER_OR_ZERO(greenBits);
   1121    PREFER_LARGER_OR_ZERO(blueBits);
   1122    PREFER_LARGER_OR_ZERO(alphaBits);
   1123 
   1124    PREFER_SMALLER(rgbBits);
   1125 
   1126    if (((*a)->doubleBufferMode != (*b)->doubleBufferMode)) {
   1127       /* Prefer single-buffer.
   1128        */
   1129       return (!(*a)->doubleBufferMode) ? -1 : 1;
   1130    }
   1131 
   1132    PREFER_SMALLER(numAuxBuffers);
   1133 
   1134    PREFER_SMALLER(sampleBuffers);
   1135    PREFER_SMALLER(samples);
   1136 
   1137    PREFER_LARGER_OR_ZERO(depthBits);
   1138    PREFER_SMALLER(stencilBits);
   1139 
   1140    /* This isn't quite right.  It is supposed to compare the sum of the
   1141     * components the user specifically set minimums for.
   1142     */
   1143    PREFER_LARGER_OR_ZERO(accumRedBits);
   1144    PREFER_LARGER_OR_ZERO(accumGreenBits);
   1145    PREFER_LARGER_OR_ZERO(accumBlueBits);
   1146    PREFER_LARGER_OR_ZERO(accumAlphaBits);
   1147 
   1148    PREFER_SMALLER(visualType);
   1149 
   1150    /* None of the pbuffer or fbconfig specs say that this comparison needs
   1151     * to happen at all, but it seems like it should.
   1152     */
   1153    PREFER_LARGER(maxPbufferWidth);
   1154    PREFER_LARGER(maxPbufferHeight);
   1155    PREFER_LARGER(maxPbufferPixels);
   1156 
   1157    return 0;
   1158 }
   1159 
   1160 
   1161 /**
   1162  * Selects and sorts a subset of the supplied configs based on the attributes.
   1163  * This function forms to basis of \c glXChooseFBConfig and
   1164  * \c glXChooseFBConfigSGIX.
   1165  *
   1166  * \param configs   Array of pointers to possible configs.  The elements of
   1167  *                  this array that do not meet the criteria will be set to
   1168  *                  NULL.  The remaining elements will be sorted according to
   1169  *                  the various visual / FBConfig selection rules.
   1170  * \param num_configs  Number of elements in the \c configs array.
   1171  * \param attribList   Attributes used select from \c configs.  This array is
   1172  *                     terminated by a \c None tag.  The array is of the form
   1173  *                     expected by \c glXChooseFBConfig (where every tag has a
   1174  *                     value).
   1175  * \returns The number of valid elements left in \c configs.
   1176  *
   1177  * \sa glXChooseFBConfig, glXChooseFBConfigSGIX
   1178  */
   1179 static int
   1180 choose_fbconfig(struct glx_config ** configs, int num_configs,
   1181               const int *attribList)
   1182 {
   1183    struct glx_config test_config;
   1184    int base;
   1185    int i;
   1186 
   1187    /* This is a fairly direct implementation of the selection method
   1188     * described by GLX_SGIX_fbconfig.  Start by culling out all the
   1189     * configs that are not compatible with the selected parameter
   1190     * list.
   1191     */
   1192 
   1193    init_fbconfig_for_chooser(&test_config, GL_TRUE);
   1194    __glXInitializeVisualConfigFromTags(&test_config, 512,
   1195                                        (const INT32 *) attribList,
   1196                                        GL_TRUE, GL_TRUE);
   1197 
   1198    base = 0;
   1199    for (i = 0; i < num_configs; i++) {
   1200       if (fbconfigs_compatible(&test_config, configs[i])) {
   1201          configs[base] = configs[i];
   1202          base++;
   1203       }
   1204    }
   1205 
   1206    if (base == 0) {
   1207       return 0;
   1208    }
   1209 
   1210    if (base < num_configs) {
   1211       (void) memset(&configs[base], 0, sizeof(void *) * (num_configs - base));
   1212    }
   1213 
   1214    /* After the incompatible configs are removed, the resulting
   1215     * list is sorted according to the rules set out in the various
   1216     * specifications.
   1217     */
   1218 
   1219    qsort(configs, base, sizeof(struct glx_config *),
   1220          (int (*)(const void *, const void *)) fbconfig_compare);
   1221    return base;
   1222 }
   1223 
   1224 
   1225 
   1226 
   1227 /*
   1228 ** Return the visual that best matches the template.  Return None if no
   1229 ** visual matches the template.
   1230 */
   1231 _GLX_PUBLIC XVisualInfo *
   1232 glXChooseVisual(Display * dpy, int screen, int *attribList)
   1233 {
   1234    XVisualInfo *visualList = NULL;
   1235    struct glx_display *priv;
   1236    struct glx_screen *psc;
   1237    struct glx_config test_config;
   1238    struct glx_config *config;
   1239    struct glx_config *best_config = NULL;
   1240 
   1241    /*
   1242     ** Get a list of all visuals, return if list is empty
   1243     */
   1244    if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
   1245       return None;
   1246    }
   1247 
   1248 
   1249    /*
   1250     ** Build a template from the defaults and the attribute list
   1251     ** Free visual list and return if an unexpected token is encountered
   1252     */
   1253    init_fbconfig_for_chooser(&test_config, GL_FALSE);
   1254    __glXInitializeVisualConfigFromTags(&test_config, 512,
   1255                                        (const INT32 *) attribList,
   1256                                        GL_TRUE, GL_FALSE);
   1257 
   1258    /*
   1259     ** Eliminate visuals that don't meet minimum requirements
   1260     ** Compute a score for those that do
   1261     ** Remember which visual, if any, got the highest score
   1262     ** If no visual is acceptable, return None
   1263     ** Otherwise, create an XVisualInfo list with just the selected X visual
   1264     ** and return this.
   1265     */
   1266    for (config = psc->visuals; config != NULL; config = config->next) {
   1267       if (fbconfigs_compatible(&test_config, config)
   1268           && ((best_config == NULL) ||
   1269               (fbconfig_compare (&config, &best_config) < 0))) {
   1270          XVisualInfo visualTemplate;
   1271          XVisualInfo *newList;
   1272          int i;
   1273 
   1274          visualTemplate.screen = screen;
   1275          visualTemplate.visualid = config->visualID;
   1276          newList = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask,
   1277                                   &visualTemplate, &i);
   1278 
   1279          if (newList) {
   1280             free(visualList);
   1281             visualList = newList;
   1282             best_config = config;
   1283          }
   1284       }
   1285    }
   1286 
   1287 #ifdef GLX_USE_APPLEGL
   1288    if(visualList && env_var_as_boolean("LIBGL_DUMP_VISUALID", false)) {
   1289       printf("visualid 0x%lx\n", visualList[0].visualid);
   1290    }
   1291 #endif
   1292 
   1293    return visualList;
   1294 }
   1295 
   1296 
   1297 _GLX_PUBLIC const char *
   1298 glXQueryExtensionsString(Display * dpy, int screen)
   1299 {
   1300    struct glx_screen *psc;
   1301    struct glx_display *priv;
   1302 
   1303    if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
   1304       return NULL;
   1305    }
   1306 
   1307    if (!psc->effectiveGLXexts) {
   1308       if (!psc->serverGLXexts) {
   1309          psc->serverGLXexts =
   1310             __glXQueryServerString(dpy, priv->majorOpcode, screen,
   1311                                    GLX_EXTENSIONS);
   1312       }
   1313 
   1314       __glXCalculateUsableExtensions(psc,
   1315 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
   1316                                      (psc->driScreen != NULL),
   1317 #else
   1318                                      GL_FALSE,
   1319 #endif
   1320                                      priv->minorVersion);
   1321    }
   1322 
   1323    return psc->effectiveGLXexts;
   1324 }
   1325 
   1326 _GLX_PUBLIC const char *
   1327 glXGetClientString(Display * dpy, int name)
   1328 {
   1329    (void) dpy;
   1330 
   1331    switch (name) {
   1332    case GLX_VENDOR:
   1333       return (__glXGLXClientVendorName);
   1334    case GLX_VERSION:
   1335       return (__glXGLXClientVersion);
   1336    case GLX_EXTENSIONS:
   1337       return (__glXGetClientExtensions());
   1338    default:
   1339       return NULL;
   1340    }
   1341 }
   1342 
   1343 _GLX_PUBLIC const char *
   1344 glXQueryServerString(Display * dpy, int screen, int name)
   1345 {
   1346    struct glx_screen *psc;
   1347    struct glx_display *priv;
   1348    const char **str;
   1349 
   1350 
   1351    if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
   1352       return NULL;
   1353    }
   1354 
   1355    switch (name) {
   1356    case GLX_VENDOR:
   1357       str = &priv->serverGLXvendor;
   1358       break;
   1359    case GLX_VERSION:
   1360       str = &priv->serverGLXversion;
   1361       break;
   1362    case GLX_EXTENSIONS:
   1363       str = &psc->serverGLXexts;
   1364       break;
   1365    default:
   1366       return NULL;
   1367    }
   1368 
   1369    if (*str == NULL) {
   1370       *str = __glXQueryServerString(dpy, priv->majorOpcode, screen, name);
   1371    }
   1372 
   1373    return *str;
   1374 }
   1375 
   1376 
   1377 /*
   1378 ** EXT_import_context
   1379 */
   1380 
   1381 _GLX_PUBLIC Display *
   1382 glXGetCurrentDisplay(void)
   1383 {
   1384    struct glx_context *gc = __glXGetCurrentContext();
   1385    if (gc == &dummyContext)
   1386       return NULL;
   1387    return gc->currentDpy;
   1388 }
   1389 
   1390 _GLX_PUBLIC
   1391 GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
   1392           glXGetCurrentDisplay)
   1393 
   1394 #ifndef GLX_USE_APPLEGL
   1395 _GLX_PUBLIC GLXContext
   1396 glXImportContextEXT(Display *dpy, GLXContextID contextID)
   1397 {
   1398    struct glx_display *priv = __glXInitialize(dpy);
   1399    struct glx_screen *psc = NULL;
   1400    xGLXQueryContextReply reply;
   1401    CARD8 opcode;
   1402    struct glx_context *ctx;
   1403    int i, renderType = GLX_RGBA_TYPE; /* By default, assume RGBA context */
   1404    XID share = None;
   1405    struct glx_config *mode = NULL;
   1406    uint32_t fbconfigID = 0;
   1407    uint32_t visualID = 0;
   1408    uint32_t screen = 0;
   1409    Bool got_screen = False;
   1410 
   1411    if (priv == NULL)
   1412       return NULL;
   1413 
   1414    /* The GLX_EXT_import_context spec says:
   1415     *
   1416     *     "If <contextID> does not refer to a valid context, then a BadContext
   1417     *     error is generated; if <contextID> refers to direct rendering
   1418     *     context then no error is generated but glXImportContextEXT returns
   1419     *     NULL."
   1420     *
   1421     * If contextID is None, generate BadContext on the client-side.  Other
   1422     * sorts of invalid contexts will be detected by the server in the
   1423     * __glXIsDirect call.
   1424     */
   1425    if (contextID == None) {
   1426       __glXSendError(dpy, GLXBadContext, contextID, X_GLXIsDirect, false);
   1427       return NULL;
   1428    }
   1429 
   1430    if (__glXIsDirect(dpy, contextID))
   1431       return NULL;
   1432 
   1433    opcode = __glXSetupForCommand(dpy);
   1434    if (!opcode)
   1435       return 0;
   1436 
   1437    /* Send the glXQueryContextInfoEXT request */
   1438    LockDisplay(dpy);
   1439 
   1440    if (priv->majorVersion > 1 || priv->minorVersion >= 3) {
   1441       xGLXQueryContextReq *req;
   1442 
   1443       GetReq(GLXQueryContext, req);
   1444 
   1445       req->reqType = opcode;
   1446       req->glxCode = X_GLXQueryContext;
   1447       req->context = contextID;
   1448    }
   1449    else {
   1450       xGLXVendorPrivateReq *vpreq;
   1451       xGLXQueryContextInfoEXTReq *req;
   1452 
   1453       GetReqExtra(GLXVendorPrivate,
   1454 		  sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
   1455 		  vpreq);
   1456       req = (xGLXQueryContextInfoEXTReq *) vpreq;
   1457       req->reqType = opcode;
   1458       req->glxCode = X_GLXVendorPrivateWithReply;
   1459       req->vendorCode = X_GLXvop_QueryContextInfoEXT;
   1460       req->context = contextID;
   1461    }
   1462 
   1463    if (_XReply(dpy, (xReply *) & reply, 0, False) &&
   1464        reply.n < (INT32_MAX / 2)) {
   1465 
   1466       for (i = 0; i < reply.n * 2; i++) {
   1467          int prop[2];
   1468 
   1469          _XRead(dpy, (char *)prop, sizeof(prop));
   1470          switch (prop[0]) {
   1471          case GLX_SCREEN:
   1472             screen = prop[1];
   1473             got_screen = True;
   1474             break;
   1475          case GLX_SHARE_CONTEXT_EXT:
   1476             share = prop[1];
   1477             break;
   1478          case GLX_VISUAL_ID_EXT:
   1479             visualID = prop[1];
   1480             break;
   1481          case GLX_FBCONFIG_ID:
   1482             fbconfigID = prop[1];
   1483             break;
   1484          case GLX_RENDER_TYPE:
   1485             renderType = prop[1];
   1486             break;
   1487          }
   1488       }
   1489    }
   1490    UnlockDisplay(dpy);
   1491    SyncHandle();
   1492 
   1493    if (!got_screen)
   1494       return NULL;
   1495 
   1496    psc = GetGLXScreenConfigs(dpy, screen);
   1497    if (psc == NULL)
   1498       return NULL;
   1499 
   1500    if (fbconfigID != 0) {
   1501       mode = glx_config_find_fbconfig(psc->configs, fbconfigID);
   1502    } else if (visualID != 0) {
   1503       mode = glx_config_find_visual(psc->visuals, visualID);
   1504    }
   1505 
   1506    if (mode == NULL)
   1507       return NULL;
   1508 
   1509    ctx = indirect_create_context(psc, mode, NULL, renderType);
   1510    if (ctx == NULL)
   1511       return NULL;
   1512 
   1513    ctx->xid = contextID;
   1514    ctx->imported = GL_TRUE;
   1515    ctx->share_xid = share;
   1516 
   1517    return (GLXContext) ctx;
   1518 }
   1519 
   1520 #endif
   1521 
   1522 _GLX_PUBLIC int
   1523 glXQueryContext(Display * dpy, GLXContext ctx_user, int attribute, int *value)
   1524 {
   1525    struct glx_context *ctx = (struct glx_context *) ctx_user;
   1526 
   1527    switch (attribute) {
   1528       case GLX_SHARE_CONTEXT_EXT:
   1529       *value = ctx->share_xid;
   1530       break;
   1531    case GLX_VISUAL_ID_EXT:
   1532       *value = ctx->config ? ctx->config->visualID : None;
   1533       break;
   1534    case GLX_SCREEN:
   1535       *value = ctx->screen;
   1536       break;
   1537    case GLX_FBCONFIG_ID:
   1538       *value = ctx->config ? ctx->config->fbconfigID : None;
   1539       break;
   1540    case GLX_RENDER_TYPE:
   1541       *value = ctx->renderType;
   1542       break;
   1543    default:
   1544       return GLX_BAD_ATTRIBUTE;
   1545    }
   1546    return Success;
   1547 }
   1548 
   1549 _GLX_PUBLIC
   1550 GLX_ALIAS(int, glXQueryContextInfoEXT,
   1551           (Display * dpy, GLXContext ctx, int attribute, int *value),
   1552           (dpy, ctx, attribute, value), glXQueryContext)
   1553 
   1554 _GLX_PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx_user)
   1555 {
   1556    struct glx_context *ctx = (struct glx_context *) ctx_user;
   1557 
   1558    return (ctx == NULL) ? None : ctx->xid;
   1559 }
   1560 
   1561 _GLX_PUBLIC void
   1562 glXFreeContextEXT(Display *dpy, GLXContext ctx)
   1563 {
   1564    struct glx_context *gc = (struct glx_context *) ctx;
   1565 
   1566    if (gc == NULL || gc->xid == None)
   1567       return;
   1568 
   1569    /* The GLX_EXT_import_context spec says:
   1570     *
   1571     *     "glXFreeContext does not free the server-side context information or
   1572     *     the XID associated with the server-side context."
   1573     *
   1574     * Don't send any protocol.  Just destroy the client-side tracking of the
   1575     * context.  Also, only release the context structure if it's not current.
   1576     */
   1577    __glXLock();
   1578    if (gc->currentDpy) {
   1579       gc->xid = None;
   1580    } else {
   1581       gc->vtable->destroy(gc);
   1582    }
   1583    __glXUnlock();
   1584 }
   1585 
   1586 _GLX_PUBLIC GLXFBConfig *
   1587 glXChooseFBConfig(Display * dpy, int screen,
   1588                   const int *attribList, int *nitems)
   1589 {
   1590    struct glx_config **config_list;
   1591    int list_size;
   1592 
   1593 
   1594    config_list = (struct glx_config **)
   1595       glXGetFBConfigs(dpy, screen, &list_size);
   1596 
   1597    if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) {
   1598       list_size = choose_fbconfig(config_list, list_size, attribList);
   1599       if (list_size == 0) {
   1600          free(config_list);
   1601          config_list = NULL;
   1602       }
   1603    }
   1604 
   1605    *nitems = list_size;
   1606    return (GLXFBConfig *) config_list;
   1607 }
   1608 
   1609 
   1610 _GLX_PUBLIC GLXContext
   1611 glXCreateNewContext(Display * dpy, GLXFBConfig fbconfig,
   1612                     int renderType, GLXContext shareList, Bool allowDirect)
   1613 {
   1614    struct glx_config *config = (struct glx_config *) fbconfig;
   1615    struct glx_config **config_list;
   1616    int list_size;
   1617    unsigned i;
   1618 
   1619    if (!config) {
   1620        __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateNewContext, false);
   1621        return NULL;
   1622    }
   1623 
   1624    config_list = (struct glx_config **)
   1625       glXGetFBConfigs(dpy, config->screen, &list_size);
   1626 
   1627    for (i = 0; i < list_size; i++) {
   1628        if (config_list[i] == config)
   1629            break;
   1630    }
   1631    free(config_list);
   1632 
   1633    if (i == list_size) {
   1634        __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateNewContext, false);
   1635        return NULL;
   1636    }
   1637 
   1638    return CreateContext(dpy, config->fbconfigID, config, shareList,
   1639 			allowDirect, X_GLXCreateNewContext, renderType,
   1640 			config->screen);
   1641 }
   1642 
   1643 
   1644 _GLX_PUBLIC GLXDrawable
   1645 glXGetCurrentReadDrawable(void)
   1646 {
   1647    struct glx_context *gc = __glXGetCurrentContext();
   1648 
   1649    return gc->currentReadable;
   1650 }
   1651 
   1652 
   1653 _GLX_PUBLIC GLXFBConfig *
   1654 glXGetFBConfigs(Display * dpy, int screen, int *nelements)
   1655 {
   1656    struct glx_display *priv = __glXInitialize(dpy);
   1657    struct glx_config **config_list = NULL;
   1658    struct glx_config *config;
   1659    unsigned num_configs = 0;
   1660    int i;
   1661 
   1662    *nelements = 0;
   1663    if (priv && (priv->screens != NULL)
   1664        && (screen >= 0) && (screen < ScreenCount(dpy))
   1665        && (priv->screens[screen]->configs != NULL)
   1666        && (priv->screens[screen]->configs->fbconfigID
   1667 	   != (int) GLX_DONT_CARE)) {
   1668 
   1669       for (config = priv->screens[screen]->configs; config != NULL;
   1670            config = config->next) {
   1671          if (config->fbconfigID != (int) GLX_DONT_CARE) {
   1672             num_configs++;
   1673          }
   1674       }
   1675 
   1676       config_list = malloc(num_configs * sizeof *config_list);
   1677       if (config_list != NULL) {
   1678          *nelements = num_configs;
   1679          i = 0;
   1680          for (config = priv->screens[screen]->configs; config != NULL;
   1681               config = config->next) {
   1682             if (config->fbconfigID != (int) GLX_DONT_CARE) {
   1683                config_list[i] = config;
   1684                i++;
   1685             }
   1686          }
   1687       }
   1688    }
   1689 
   1690    return (GLXFBConfig *) config_list;
   1691 }
   1692 
   1693 
   1694 _GLX_PUBLIC int
   1695 glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig,
   1696                      int attribute, int *value)
   1697 {
   1698    struct glx_config *config = ValidateGLXFBConfig(dpy, fbconfig);
   1699 
   1700    if (config == NULL)
   1701       return GLXBadFBConfig;
   1702 
   1703    return glx_config_get(config, attribute, value);
   1704 }
   1705 
   1706 
   1707 _GLX_PUBLIC XVisualInfo *
   1708 glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig fbconfig)
   1709 {
   1710    XVisualInfo visualTemplate;
   1711    struct glx_config *config = (struct glx_config *) fbconfig;
   1712    int count;
   1713 
   1714    /*
   1715     ** Get a list of all visuals, return if list is empty
   1716     */
   1717    visualTemplate.visualid = config->visualID;
   1718    return XGetVisualInfo(dpy, VisualIDMask, &visualTemplate, &count);
   1719 }
   1720 
   1721 #ifndef GLX_USE_APPLEGL
   1722 /*
   1723 ** GLX_SGI_swap_control
   1724 */
   1725 static int
   1726 __glXSwapIntervalSGI(int interval)
   1727 {
   1728    xGLXVendorPrivateReq *req;
   1729    struct glx_context *gc = __glXGetCurrentContext();
   1730    struct glx_screen *psc;
   1731    Display *dpy;
   1732    CARD32 *interval_ptr;
   1733    CARD8 opcode;
   1734 
   1735    if (gc == &dummyContext) {
   1736       return GLX_BAD_CONTEXT;
   1737    }
   1738 
   1739    if (interval <= 0) {
   1740       return GLX_BAD_VALUE;
   1741    }
   1742 
   1743    psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
   1744 
   1745 #ifdef GLX_DIRECT_RENDERING
   1746    if (gc->isDirect && psc && psc->driScreen &&
   1747           psc->driScreen->setSwapInterval) {
   1748       __GLXDRIdrawable *pdraw =
   1749 	 GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
   1750       /* Simply ignore the command if the GLX drawable has been destroyed but
   1751        * the context is still bound.
   1752        */
   1753       if (pdraw)
   1754          psc->driScreen->setSwapInterval(pdraw, interval);
   1755       return 0;
   1756    }
   1757 #endif
   1758 
   1759    dpy = gc->currentDpy;
   1760    opcode = __glXSetupForCommand(dpy);
   1761    if (!opcode) {
   1762       return 0;
   1763    }
   1764 
   1765    /* Send the glXSwapIntervalSGI request */
   1766    LockDisplay(dpy);
   1767    GetReqExtra(GLXVendorPrivate, sizeof(CARD32), req);
   1768    req->reqType = opcode;
   1769    req->glxCode = X_GLXVendorPrivate;
   1770    req->vendorCode = X_GLXvop_SwapIntervalSGI;
   1771    req->contextTag = gc->currentContextTag;
   1772 
   1773    interval_ptr = (CARD32 *) (req + 1);
   1774    *interval_ptr = interval;
   1775 
   1776    UnlockDisplay(dpy);
   1777    SyncHandle();
   1778    XFlush(dpy);
   1779 
   1780    return 0;
   1781 }
   1782 
   1783 
   1784 /*
   1785 ** GLX_MESA_swap_control
   1786 */
   1787 static int
   1788 __glXSwapIntervalMESA(unsigned int interval)
   1789 {
   1790 #ifdef GLX_DIRECT_RENDERING
   1791    struct glx_context *gc = __glXGetCurrentContext();
   1792 
   1793    if (gc != &dummyContext && gc->isDirect) {
   1794       struct glx_screen *psc;
   1795 
   1796       psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
   1797       if (psc && psc->driScreen && psc->driScreen->setSwapInterval) {
   1798          __GLXDRIdrawable *pdraw =
   1799 	    GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
   1800 
   1801          /* Simply ignore the command if the GLX drawable has been destroyed but
   1802           * the context is still bound.
   1803           */
   1804          if (!pdraw)
   1805             return 0;
   1806 
   1807          return psc->driScreen->setSwapInterval(pdraw, interval);
   1808       }
   1809    }
   1810 #endif
   1811 
   1812    return GLX_BAD_CONTEXT;
   1813 }
   1814 
   1815 
   1816 static int
   1817 __glXGetSwapIntervalMESA(void)
   1818 {
   1819 #ifdef GLX_DIRECT_RENDERING
   1820    struct glx_context *gc = __glXGetCurrentContext();
   1821 
   1822    if (gc != &dummyContext && gc->isDirect) {
   1823       struct glx_screen *psc;
   1824 
   1825       psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
   1826       if (psc && psc->driScreen && psc->driScreen->getSwapInterval) {
   1827          __GLXDRIdrawable *pdraw =
   1828 	    GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
   1829          if (pdraw)
   1830             return psc->driScreen->getSwapInterval(pdraw);
   1831       }
   1832    }
   1833 #endif
   1834 
   1835    return 0;
   1836 }
   1837 
   1838 
   1839 /*
   1840 ** GLX_SGI_video_sync
   1841 */
   1842 static int
   1843 __glXGetVideoSyncSGI(unsigned int *count)
   1844 {
   1845    int64_t ust, msc, sbc;
   1846    int ret;
   1847    struct glx_context *gc = __glXGetCurrentContext();
   1848    struct glx_screen *psc;
   1849 #ifdef GLX_DIRECT_RENDERING
   1850    __GLXDRIdrawable *pdraw;
   1851 #endif
   1852 
   1853    if (gc == &dummyContext)
   1854       return GLX_BAD_CONTEXT;
   1855 
   1856 #ifdef GLX_DIRECT_RENDERING
   1857    if (!gc->isDirect)
   1858       return GLX_BAD_CONTEXT;
   1859 #endif
   1860 
   1861    psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen);
   1862 #ifdef GLX_DIRECT_RENDERING
   1863    pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
   1864 #endif
   1865 
   1866    /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
   1867     * FIXME: there should be a GLX encoding for this call.  I can find no
   1868     * FIXME: documentation for the GLX encoding.
   1869     */
   1870 #ifdef GLX_DIRECT_RENDERING
   1871    if (psc && psc->driScreen && psc->driScreen->getDrawableMSC) {
   1872       ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc);
   1873       *count = (unsigned) msc;
   1874       return (ret == True) ? 0 : GLX_BAD_CONTEXT;
   1875    }
   1876 #endif
   1877 
   1878    return GLX_BAD_CONTEXT;
   1879 }
   1880 
   1881 static int
   1882 __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
   1883 {
   1884    struct glx_context *gc = __glXGetCurrentContext();
   1885    struct glx_screen *psc;
   1886 #ifdef GLX_DIRECT_RENDERING
   1887    __GLXDRIdrawable *pdraw;
   1888 #endif
   1889    int64_t ust, msc, sbc;
   1890    int ret;
   1891 
   1892    if (divisor <= 0 || remainder < 0)
   1893       return GLX_BAD_VALUE;
   1894 
   1895    if (gc == &dummyContext)
   1896       return GLX_BAD_CONTEXT;
   1897 
   1898 #ifdef GLX_DIRECT_RENDERING
   1899    if (!gc->isDirect)
   1900       return GLX_BAD_CONTEXT;
   1901 #endif
   1902 
   1903    psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
   1904 #ifdef GLX_DIRECT_RENDERING
   1905    pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
   1906 #endif
   1907 
   1908 #ifdef GLX_DIRECT_RENDERING
   1909    if (psc && psc->driScreen && psc->driScreen->waitForMSC) {
   1910       ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc,
   1911 				       &sbc);
   1912       *count = (unsigned) msc;
   1913       return (ret == True) ? 0 : GLX_BAD_CONTEXT;
   1914    }
   1915 #endif
   1916 
   1917    return GLX_BAD_CONTEXT;
   1918 }
   1919 
   1920 #endif /* GLX_USE_APPLEGL */
   1921 
   1922 /*
   1923 ** GLX_SGIX_fbconfig
   1924 ** Many of these functions are aliased to GLX 1.3 entry points in the
   1925 ** GLX_functions table.
   1926 */
   1927 
   1928 _GLX_PUBLIC
   1929 GLX_ALIAS(int, glXGetFBConfigAttribSGIX,
   1930           (Display * dpy, GLXFBConfigSGIX config, int attribute, int *value),
   1931           (dpy, config, attribute, value), glXGetFBConfigAttrib)
   1932 
   1933 _GLX_PUBLIC GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
   1934                  (Display * dpy, int screen, int *attrib_list,
   1935                   int *nelements), (dpy, screen, attrib_list, nelements),
   1936                  glXChooseFBConfig)
   1937 
   1938 _GLX_PUBLIC GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
   1939                  (Display * dpy, GLXFBConfigSGIX config),
   1940                  (dpy, config), glXGetVisualFromFBConfig)
   1941 
   1942 _GLX_PUBLIC GLXPixmap
   1943 glXCreateGLXPixmapWithConfigSGIX(Display * dpy,
   1944                                  GLXFBConfigSGIX fbconfig,
   1945                                  Pixmap pixmap)
   1946 {
   1947 #ifndef GLX_USE_APPLEGL
   1948    xGLXVendorPrivateWithReplyReq *vpreq;
   1949    xGLXCreateGLXPixmapWithConfigSGIXReq *req;
   1950    GLXPixmap xid = None;
   1951    CARD8 opcode;
   1952    struct glx_screen *psc;
   1953 #endif
   1954    struct glx_config *config = (struct glx_config *) fbconfig;
   1955 
   1956 
   1957    if ((dpy == NULL) || (config == NULL)) {
   1958       return None;
   1959    }
   1960 #ifdef GLX_USE_APPLEGL
   1961    if(apple_glx_pixmap_create(dpy, config->screen, pixmap, config))
   1962       return None;
   1963    return pixmap;
   1964 #else
   1965 
   1966    psc = GetGLXScreenConfigs(dpy, config->screen);
   1967    if ((psc != NULL)
   1968        && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
   1969       opcode = __glXSetupForCommand(dpy);
   1970       if (!opcode) {
   1971          return None;
   1972       }
   1973 
   1974       /* Send the glXCreateGLXPixmapWithConfigSGIX request */
   1975       LockDisplay(dpy);
   1976       GetReqExtra(GLXVendorPrivateWithReply,
   1977                   sz_xGLXCreateGLXPixmapWithConfigSGIXReq -
   1978                   sz_xGLXVendorPrivateWithReplyReq, vpreq);
   1979       req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) vpreq;
   1980       req->reqType = opcode;
   1981       req->glxCode = X_GLXVendorPrivateWithReply;
   1982       req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
   1983       req->screen = config->screen;
   1984       req->fbconfig = config->fbconfigID;
   1985       req->pixmap = pixmap;
   1986       req->glxpixmap = xid = XAllocID(dpy);
   1987       UnlockDisplay(dpy);
   1988       SyncHandle();
   1989    }
   1990 
   1991    return xid;
   1992 #endif
   1993 }
   1994 
   1995 _GLX_PUBLIC GLXContext
   1996 glXCreateContextWithConfigSGIX(Display * dpy,
   1997                                GLXFBConfigSGIX fbconfig, int renderType,
   1998                                GLXContext shareList, Bool allowDirect)
   1999 {
   2000    GLXContext gc = NULL;
   2001    struct glx_config *config = (struct glx_config *) fbconfig;
   2002    struct glx_screen *psc;
   2003 
   2004 
   2005    if ((dpy == NULL) || (config == NULL)) {
   2006       return None;
   2007    }
   2008 
   2009    psc = GetGLXScreenConfigs(dpy, config->screen);
   2010    if ((psc != NULL)
   2011        && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
   2012       gc = CreateContext(dpy, config->fbconfigID, config, shareList,
   2013                          allowDirect,
   2014 			 X_GLXvop_CreateContextWithConfigSGIX, renderType,
   2015 			 config->screen);
   2016    }
   2017 
   2018    return gc;
   2019 }
   2020 
   2021 
   2022 _GLX_PUBLIC GLXFBConfigSGIX
   2023 glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis)
   2024 {
   2025    struct glx_display *priv;
   2026    struct glx_screen *psc = NULL;
   2027 
   2028    if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) == Success)
   2029        && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)
   2030        && (psc->configs->fbconfigID != (int) GLX_DONT_CARE)) {
   2031       return (GLXFBConfigSGIX) glx_config_find_visual(psc->configs,
   2032 						      vis->visualid);
   2033    }
   2034 
   2035    return NULL;
   2036 }
   2037 
   2038 #ifndef GLX_USE_APPLEGL
   2039 /*
   2040 ** GLX_SGIX_swap_group
   2041 */
   2042 static void
   2043 __glXJoinSwapGroupSGIX(Display * dpy, GLXDrawable drawable,
   2044                        GLXDrawable member)
   2045 {
   2046    (void) dpy;
   2047    (void) drawable;
   2048    (void) member;
   2049 }
   2050 
   2051 
   2052 /*
   2053 ** GLX_SGIX_swap_barrier
   2054 */
   2055 static void
   2056 __glXBindSwapBarrierSGIX(Display * dpy, GLXDrawable drawable, int barrier)
   2057 {
   2058    (void) dpy;
   2059    (void) drawable;
   2060    (void) barrier;
   2061 }
   2062 
   2063 static Bool
   2064 __glXQueryMaxSwapBarriersSGIX(Display * dpy, int screen, int *max)
   2065 {
   2066    (void) dpy;
   2067    (void) screen;
   2068    (void) max;
   2069    return False;
   2070 }
   2071 
   2072 
   2073 /*
   2074 ** GLX_OML_sync_control
   2075 */
   2076 static Bool
   2077 __glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
   2078                       int64_t * ust, int64_t * msc, int64_t * sbc)
   2079 {
   2080    struct glx_display * const priv = __glXInitialize(dpy);
   2081    int ret;
   2082 #ifdef GLX_DIRECT_RENDERING
   2083    __GLXDRIdrawable *pdraw;
   2084 #endif
   2085    struct glx_screen *psc;
   2086 
   2087    if (!priv)
   2088       return False;
   2089 
   2090 #ifdef GLX_DIRECT_RENDERING
   2091    pdraw = GetGLXDRIDrawable(dpy, drawable);
   2092    psc = pdraw ? pdraw->psc : NULL;
   2093    if (pdraw && psc->driScreen->getDrawableMSC) {
   2094       ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc);
   2095       return ret;
   2096    }
   2097 #endif
   2098 
   2099    return False;
   2100 }
   2101 
   2102 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
   2103 _X_HIDDEN GLboolean
   2104 __glxGetMscRate(struct glx_screen *psc,
   2105 		int32_t * numerator, int32_t * denominator)
   2106 {
   2107 #ifdef XF86VIDMODE
   2108    XF86VidModeModeLine mode_line;
   2109    int dot_clock;
   2110    int i;
   2111 
   2112    if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
   2113        XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line)) {
   2114       unsigned n = dot_clock * 1000;
   2115       unsigned d = mode_line.vtotal * mode_line.htotal;
   2116 
   2117 # define V_INTERLACE 0x010
   2118 # define V_DBLSCAN   0x020
   2119 
   2120       if (mode_line.flags & V_INTERLACE)
   2121          n *= 2;
   2122       else if (mode_line.flags & V_DBLSCAN)
   2123          d *= 2;
   2124 
   2125       /* The OML_sync_control spec requires that if the refresh rate is a
   2126        * whole number, that the returned numerator be equal to the refresh
   2127        * rate and the denominator be 1.
   2128        */
   2129 
   2130       if (n % d == 0) {
   2131          n /= d;
   2132          d = 1;
   2133       }
   2134       else {
   2135          static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
   2136 
   2137          /* This is a poor man's way to reduce a fraction.  It's far from
   2138           * perfect, but it will work well enough for this situation.
   2139           */
   2140 
   2141          for (i = 0; f[i] != 0; i++) {
   2142             while (n % f[i] == 0 && d % f[i] == 0) {
   2143                d /= f[i];
   2144                n /= f[i];
   2145             }
   2146          }
   2147       }
   2148 
   2149       *numerator = n;
   2150       *denominator = d;
   2151 
   2152       return True;
   2153    }
   2154    else
   2155 #endif
   2156 
   2157    return False;
   2158 }
   2159 #endif
   2160 
   2161 /**
   2162  * Determine the refresh rate of the specified drawable and display.
   2163  *
   2164  * \param dpy          Display whose refresh rate is to be determined.
   2165  * \param drawable     Drawable whose refresh rate is to be determined.
   2166  * \param numerator    Numerator of the refresh rate.
   2167  * \param demoninator  Denominator of the refresh rate.
   2168  * \return  If the refresh rate for the specified display and drawable could
   2169  *          be calculated, True is returned.  Otherwise False is returned.
   2170  *
   2171  * \note This function is implemented entirely client-side.  A lot of other
   2172  *       functionality is required to export GLX_OML_sync_control, so on
   2173  *       XFree86 this function can be called for direct-rendering contexts
   2174  *       when GLX_OML_sync_control appears in the client extension string.
   2175  */
   2176 
   2177 _X_HIDDEN GLboolean
   2178 __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
   2179                    int32_t * numerator, int32_t * denominator)
   2180 {
   2181 #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
   2182    __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable);
   2183 
   2184    if (draw == NULL)
   2185       return False;
   2186 
   2187    return __glxGetMscRate(draw->psc, numerator, denominator);
   2188 #else
   2189    (void) dpy;
   2190    (void) drawable;
   2191    (void) numerator;
   2192    (void) denominator;
   2193 #endif
   2194    return False;
   2195 }
   2196 
   2197 
   2198 static int64_t
   2199 __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
   2200                        int64_t target_msc, int64_t divisor, int64_t remainder)
   2201 {
   2202    struct glx_context *gc = __glXGetCurrentContext();
   2203 #ifdef GLX_DIRECT_RENDERING
   2204    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
   2205    struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
   2206 #endif
   2207 
   2208    if (gc == &dummyContext) /* no GLX for this */
   2209       return -1;
   2210 
   2211 #ifdef GLX_DIRECT_RENDERING
   2212    if (!pdraw || !gc->isDirect)
   2213       return -1;
   2214 #endif
   2215 
   2216    /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
   2217     * error", but it also says "It [glXSwapBuffersMscOML] will return a value
   2218     * of -1 if the function failed because of errors detected in the input
   2219     * parameters"
   2220     */
   2221    if (divisor < 0 || remainder < 0 || target_msc < 0)
   2222       return -1;
   2223    if (divisor > 0 && remainder >= divisor)
   2224       return -1;
   2225 
   2226    if (target_msc == 0 && divisor == 0 && remainder == 0)
   2227       remainder = 1;
   2228 
   2229 #ifdef GLX_DIRECT_RENDERING
   2230    if (psc->driScreen && psc->driScreen->swapBuffers)
   2231       return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor,
   2232 					    remainder, False);
   2233 #endif
   2234 
   2235    return -1;
   2236 }
   2237 
   2238 
   2239 static Bool
   2240 __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
   2241                    int64_t target_msc, int64_t divisor,
   2242                    int64_t remainder, int64_t * ust,
   2243                    int64_t * msc, int64_t * sbc)
   2244 {
   2245 #ifdef GLX_DIRECT_RENDERING
   2246    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
   2247    struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
   2248    int ret;
   2249 #endif
   2250 
   2251 
   2252    /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
   2253     * error", but the return type in the spec is Bool.
   2254     */
   2255    if (divisor < 0 || remainder < 0 || target_msc < 0)
   2256       return False;
   2257    if (divisor > 0 && remainder >= divisor)
   2258       return False;
   2259 
   2260 #ifdef GLX_DIRECT_RENDERING
   2261    if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
   2262       ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder,
   2263 				       ust, msc, sbc);
   2264       return ret;
   2265    }
   2266 #endif
   2267 
   2268    return False;
   2269 }
   2270 
   2271 
   2272 static Bool
   2273 __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
   2274                    int64_t target_sbc, int64_t * ust,
   2275                    int64_t * msc, int64_t * sbc)
   2276 {
   2277 #ifdef GLX_DIRECT_RENDERING
   2278    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
   2279    struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
   2280    int ret;
   2281 #endif
   2282 
   2283    /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
   2284     * error", but the return type in the spec is Bool.
   2285     */
   2286    if (target_sbc < 0)
   2287       return False;
   2288 
   2289 #ifdef GLX_DIRECT_RENDERING
   2290    if (pdraw && psc->driScreen && psc->driScreen->waitForSBC) {
   2291       ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc);
   2292       return ret;
   2293    }
   2294 #endif
   2295 
   2296    return False;
   2297 }
   2298 
   2299 /*@}*/
   2300 
   2301 
   2302 /**
   2303  * Mesa extension stubs.  These will help reduce portability problems.
   2304  */
   2305 /*@{*/
   2306 
   2307 /**
   2308  * Release all buffers associated with the specified GLX drawable.
   2309  *
   2310  * \todo
   2311  * This function was intended for stand-alone Mesa.  The issue there is that
   2312  * the library doesn't get any notification when a window is closed.  In
   2313  * DRI there is a similar but slightly different issue.  When GLX 1.3 is
   2314  * supported, there are 3 different functions to destroy a drawable.  It
   2315  * should be possible to create GLX protocol (or have it determine which
   2316  * protocol to use based on the type of the drawable) to have one function
   2317  * do the work of 3.  For the direct-rendering case, this function could
   2318  * just call the driver's \c __DRIdrawableRec::destroyDrawable function.
   2319  * This would reduce the frequency with which \c __driGarbageCollectDrawables
   2320  * would need to be used.  This really should be done as part of the new DRI
   2321  * interface work.
   2322  *
   2323  * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt
   2324  *     __driGarbageCollectDrawables
   2325  *     glXDestroyGLXPixmap
   2326  *     glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
   2327  *     glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
   2328  */
   2329 static Bool
   2330 __glXReleaseBuffersMESA(Display * dpy, GLXDrawable d)
   2331 {
   2332    (void) dpy;
   2333    (void) d;
   2334    return False;
   2335 }
   2336 
   2337 
   2338 _GLX_PUBLIC GLXPixmap
   2339 glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual,
   2340                        Pixmap pixmap, Colormap cmap)
   2341 {
   2342    (void) dpy;
   2343    (void) visual;
   2344    (void) pixmap;
   2345    (void) cmap;
   2346    return 0;
   2347 }
   2348 
   2349 /*@}*/
   2350 
   2351 
   2352 /**
   2353  * GLX_MESA_copy_sub_buffer
   2354  */
   2355 #define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
   2356 static void
   2357 __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
   2358                        int x, int y, int width, int height)
   2359 {
   2360    xGLXVendorPrivateReq *req;
   2361    struct glx_context *gc;
   2362    GLXContextTag tag;
   2363    CARD32 *drawable_ptr;
   2364    INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
   2365    CARD8 opcode;
   2366 
   2367 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
   2368    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
   2369    if (pdraw != NULL) {
   2370       struct glx_screen *psc = pdraw->psc;
   2371       if (psc->driScreen->copySubBuffer != NULL) {
   2372          (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height, True);
   2373       }
   2374 
   2375       return;
   2376    }
   2377 #endif
   2378 
   2379    opcode = __glXSetupForCommand(dpy);
   2380    if (!opcode)
   2381       return;
   2382 
   2383    /*
   2384     ** The calling thread may or may not have a current context.  If it
   2385     ** does, send the context tag so the server can do a flush.
   2386     */
   2387    gc = __glXGetCurrentContext();
   2388    if ((gc != &dummyContext) && (dpy == gc->currentDpy) &&
   2389        ((drawable == gc->currentDrawable) ||
   2390         (drawable == gc->currentReadable))) {
   2391       tag = gc->currentContextTag;
   2392    }
   2393    else {
   2394       tag = 0;
   2395    }
   2396 
   2397    LockDisplay(dpy);
   2398    GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4, req);
   2399    req->reqType = opcode;
   2400    req->glxCode = X_GLXVendorPrivate;
   2401    req->vendorCode = X_GLXvop_CopySubBufferMESA;
   2402    req->contextTag = tag;
   2403 
   2404    drawable_ptr = (CARD32 *) (req + 1);
   2405    x_ptr = (INT32 *) (drawable_ptr + 1);
   2406    y_ptr = (INT32 *) (drawable_ptr + 2);
   2407    w_ptr = (INT32 *) (drawable_ptr + 3);
   2408    h_ptr = (INT32 *) (drawable_ptr + 4);
   2409 
   2410    *drawable_ptr = drawable;
   2411    *x_ptr = x;
   2412    *y_ptr = y;
   2413    *w_ptr = width;
   2414    *h_ptr = height;
   2415 
   2416    UnlockDisplay(dpy);
   2417    SyncHandle();
   2418 }
   2419 
   2420 /*@{*/
   2421 static void
   2422 __glXBindTexImageEXT(Display * dpy,
   2423                      GLXDrawable drawable, int buffer, const int *attrib_list)
   2424 {
   2425    struct glx_context *gc = __glXGetCurrentContext();
   2426 
   2427    if (gc->vtable->bind_tex_image == NULL)
   2428       return;
   2429 
   2430    gc->vtable->bind_tex_image(dpy, drawable, buffer, attrib_list);
   2431 }
   2432 
   2433 static void
   2434 __glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer)
   2435 {
   2436    struct glx_context *gc = __glXGetCurrentContext();
   2437 
   2438    if (gc->vtable->release_tex_image == NULL)
   2439       return;
   2440 
   2441    gc->vtable->release_tex_image(dpy, drawable, buffer);
   2442 }
   2443 
   2444 /*@}*/
   2445 
   2446 #endif /* GLX_USE_APPLEGL */
   2447 
   2448 /*
   2449 ** glXGetProcAddress support
   2450 */
   2451 
   2452 struct name_address_pair
   2453 {
   2454    const char *Name;
   2455    GLvoid *Address;
   2456 };
   2457 
   2458 #define GLX_FUNCTION(f) { # f, (GLvoid *) f }
   2459 #define GLX_FUNCTION2(n,f) { # n, (GLvoid *) f }
   2460 
   2461 static const struct name_address_pair GLX_functions[] = {
   2462    /*** GLX_VERSION_1_0 ***/
   2463    GLX_FUNCTION(glXChooseVisual),
   2464    GLX_FUNCTION(glXCopyContext),
   2465    GLX_FUNCTION(glXCreateContext),
   2466    GLX_FUNCTION(glXCreateGLXPixmap),
   2467    GLX_FUNCTION(glXDestroyContext),
   2468    GLX_FUNCTION(glXDestroyGLXPixmap),
   2469    GLX_FUNCTION(glXGetConfig),
   2470    GLX_FUNCTION(glXGetCurrentContext),
   2471    GLX_FUNCTION(glXGetCurrentDrawable),
   2472    GLX_FUNCTION(glXIsDirect),
   2473    GLX_FUNCTION(glXMakeCurrent),
   2474    GLX_FUNCTION(glXQueryExtension),
   2475    GLX_FUNCTION(glXQueryVersion),
   2476    GLX_FUNCTION(glXSwapBuffers),
   2477    GLX_FUNCTION(glXUseXFont),
   2478    GLX_FUNCTION(glXWaitGL),
   2479    GLX_FUNCTION(glXWaitX),
   2480 
   2481    /*** GLX_VERSION_1_1 ***/
   2482    GLX_FUNCTION(glXGetClientString),
   2483    GLX_FUNCTION(glXQueryExtensionsString),
   2484    GLX_FUNCTION(glXQueryServerString),
   2485 
   2486    /*** GLX_VERSION_1_2 ***/
   2487    GLX_FUNCTION(glXGetCurrentDisplay),
   2488 
   2489    /*** GLX_VERSION_1_3 ***/
   2490    GLX_FUNCTION(glXChooseFBConfig),
   2491    GLX_FUNCTION(glXCreateNewContext),
   2492    GLX_FUNCTION(glXCreatePbuffer),
   2493    GLX_FUNCTION(glXCreatePixmap),
   2494    GLX_FUNCTION(glXCreateWindow),
   2495    GLX_FUNCTION(glXDestroyPbuffer),
   2496    GLX_FUNCTION(glXDestroyPixmap),
   2497    GLX_FUNCTION(glXDestroyWindow),
   2498    GLX_FUNCTION(glXGetCurrentReadDrawable),
   2499    GLX_FUNCTION(glXGetFBConfigAttrib),
   2500    GLX_FUNCTION(glXGetFBConfigs),
   2501    GLX_FUNCTION(glXGetSelectedEvent),
   2502    GLX_FUNCTION(glXGetVisualFromFBConfig),
   2503    GLX_FUNCTION(glXMakeContextCurrent),
   2504    GLX_FUNCTION(glXQueryContext),
   2505    GLX_FUNCTION(glXQueryDrawable),
   2506    GLX_FUNCTION(glXSelectEvent),
   2507 
   2508 #ifndef GLX_USE_APPLEGL
   2509    /*** GLX_SGI_swap_control ***/
   2510    GLX_FUNCTION2(glXSwapIntervalSGI, __glXSwapIntervalSGI),
   2511 
   2512    /*** GLX_SGI_video_sync ***/
   2513    GLX_FUNCTION2(glXGetVideoSyncSGI, __glXGetVideoSyncSGI),
   2514    GLX_FUNCTION2(glXWaitVideoSyncSGI, __glXWaitVideoSyncSGI),
   2515 
   2516    /*** GLX_SGI_make_current_read ***/
   2517    GLX_FUNCTION2(glXMakeCurrentReadSGI, glXMakeContextCurrent),
   2518    GLX_FUNCTION2(glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable),
   2519 
   2520    /*** GLX_EXT_import_context ***/
   2521    GLX_FUNCTION(glXFreeContextEXT),
   2522    GLX_FUNCTION(glXGetContextIDEXT),
   2523    GLX_FUNCTION2(glXGetCurrentDisplayEXT, glXGetCurrentDisplay),
   2524    GLX_FUNCTION(glXImportContextEXT),
   2525    GLX_FUNCTION2(glXQueryContextInfoEXT, glXQueryContext),
   2526 #endif
   2527 
   2528    /*** GLX_SGIX_fbconfig ***/
   2529    GLX_FUNCTION2(glXGetFBConfigAttribSGIX, glXGetFBConfigAttrib),
   2530    GLX_FUNCTION2(glXChooseFBConfigSGIX, glXChooseFBConfig),
   2531    GLX_FUNCTION(glXCreateGLXPixmapWithConfigSGIX),
   2532    GLX_FUNCTION(glXCreateContextWithConfigSGIX),
   2533    GLX_FUNCTION2(glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig),
   2534    GLX_FUNCTION(glXGetFBConfigFromVisualSGIX),
   2535 
   2536 #ifndef GLX_USE_APPLEGL
   2537    /*** GLX_SGIX_pbuffer ***/
   2538    GLX_FUNCTION(glXCreateGLXPbufferSGIX),
   2539    GLX_FUNCTION(glXDestroyGLXPbufferSGIX),
   2540    GLX_FUNCTION(glXQueryGLXPbufferSGIX),
   2541    GLX_FUNCTION(glXSelectEventSGIX),
   2542    GLX_FUNCTION(glXGetSelectedEventSGIX),
   2543 
   2544    /*** GLX_SGIX_swap_group ***/
   2545    GLX_FUNCTION2(glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX),
   2546 
   2547    /*** GLX_SGIX_swap_barrier ***/
   2548    GLX_FUNCTION2(glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX),
   2549    GLX_FUNCTION2(glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX),
   2550 
   2551    /*** GLX_MESA_copy_sub_buffer ***/
   2552    GLX_FUNCTION2(glXCopySubBufferMESA, __glXCopySubBufferMESA),
   2553 
   2554    /*** GLX_MESA_pixmap_colormap ***/
   2555    GLX_FUNCTION(glXCreateGLXPixmapMESA),
   2556 
   2557    /*** GLX_MESA_release_buffers ***/
   2558    GLX_FUNCTION2(glXReleaseBuffersMESA, __glXReleaseBuffersMESA),
   2559 
   2560    /*** GLX_MESA_swap_control ***/
   2561    GLX_FUNCTION2(glXSwapIntervalMESA, __glXSwapIntervalMESA),
   2562    GLX_FUNCTION2(glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA),
   2563 #endif
   2564 
   2565    /*** GLX_ARB_get_proc_address ***/
   2566    GLX_FUNCTION(glXGetProcAddressARB),
   2567 
   2568    /*** GLX 1.4 ***/
   2569    GLX_FUNCTION2(glXGetProcAddress, glXGetProcAddressARB),
   2570 
   2571 #ifndef GLX_USE_APPLEGL
   2572    /*** GLX_OML_sync_control ***/
   2573    GLX_FUNCTION2(glXWaitForSbcOML, __glXWaitForSbcOML),
   2574    GLX_FUNCTION2(glXWaitForMscOML, __glXWaitForMscOML),
   2575    GLX_FUNCTION2(glXSwapBuffersMscOML, __glXSwapBuffersMscOML),
   2576    GLX_FUNCTION2(glXGetMscRateOML, __glXGetMscRateOML),
   2577    GLX_FUNCTION2(glXGetSyncValuesOML, __glXGetSyncValuesOML),
   2578 
   2579    /*** GLX_EXT_texture_from_pixmap ***/
   2580    GLX_FUNCTION2(glXBindTexImageEXT, __glXBindTexImageEXT),
   2581    GLX_FUNCTION2(glXReleaseTexImageEXT, __glXReleaseTexImageEXT),
   2582 #endif
   2583 
   2584 #if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_DRM)
   2585    /*** DRI configuration ***/
   2586    GLX_FUNCTION(glXGetScreenDriver),
   2587    GLX_FUNCTION(glXGetDriverConfig),
   2588 #endif
   2589 
   2590    /*** GLX_ARB_create_context and GLX_ARB_create_context_profile ***/
   2591    GLX_FUNCTION(glXCreateContextAttribsARB),
   2592 
   2593    /*** GLX_MESA_query_renderer ***/
   2594    GLX_FUNCTION(glXQueryRendererIntegerMESA),
   2595    GLX_FUNCTION(glXQueryRendererStringMESA),
   2596    GLX_FUNCTION(glXQueryCurrentRendererIntegerMESA),
   2597    GLX_FUNCTION(glXQueryCurrentRendererStringMESA),
   2598 
   2599    {NULL, NULL}                 /* end of list */
   2600 };
   2601 
   2602 static const GLvoid *
   2603 get_glx_proc_address(const char *funcName)
   2604 {
   2605    GLuint i;
   2606 
   2607    /* try static functions */
   2608    for (i = 0; GLX_functions[i].Name; i++) {
   2609       if (strcmp(GLX_functions[i].Name, funcName) == 0)
   2610          return GLX_functions[i].Address;
   2611    }
   2612 
   2613    return NULL;
   2614 }
   2615 
   2616 /**
   2617  * Get the address of a named GL function.  This is the pre-GLX 1.4 name for
   2618  * \c glXGetProcAddress.
   2619  *
   2620  * \param procName  Name of a GL or GLX function.
   2621  * \returns         A pointer to the named function
   2622  *
   2623  * \sa glXGetProcAddress
   2624  */
   2625 _GLX_PUBLIC void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
   2626 {
   2627    typedef void (*gl_function) (void);
   2628    gl_function f;
   2629 
   2630 
   2631    /* Search the table of GLX and internal functions first.  If that
   2632     * fails and the supplied name could be a valid core GL name, try
   2633     * searching the core GL function table.  This check is done to prevent
   2634     * DRI based drivers from searching the core GL function table for
   2635     * internal API functions.
   2636     */
   2637    f = (gl_function) get_glx_proc_address((const char *) procName);
   2638    if ((f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
   2639        && (procName[2] != 'X')) {
   2640 #ifdef GLX_INDIRECT_RENDERING
   2641       f = (gl_function) __indirect_get_proc_address((const char *) procName);
   2642 #endif
   2643       if (!f)
   2644          f = (gl_function) _glapi_get_proc_address((const char *) procName);
   2645       if (!f) {
   2646          struct glx_context *gc = __glXGetCurrentContext();
   2647 
   2648          if (gc != NULL && gc->vtable->get_proc_address != NULL)
   2649             f = gc->vtable->get_proc_address((const char *) procName);
   2650       }
   2651    }
   2652    return f;
   2653 }
   2654 
   2655 /**
   2656  * Get the address of a named GL function.  This is the GLX 1.4 name for
   2657  * \c glXGetProcAddressARB.
   2658  *
   2659  * \param procName  Name of a GL or GLX function.
   2660  * \returns         A pointer to the named function
   2661  *
   2662  * \sa glXGetProcAddressARB
   2663  */
   2664 _GLX_PUBLIC
   2665 GLX_ALIAS(__GLXextFuncPtr, glXGetProcAddress,
   2666           (const GLubyte * procName),
   2667           (procName), glXGetProcAddressARB)
   2668 
   2669 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
   2670 /**
   2671  * Get the unadjusted system time (UST).  Currently, the UST is measured in
   2672  * microseconds since Epoc.  The actual resolution of the UST may vary from
   2673  * system to system, and the units may vary from release to release.
   2674  * Drivers should not call this function directly.  They should instead use
   2675  * \c glXGetProcAddress to obtain a pointer to the function.
   2676  *
   2677  * \param ust Location to store the 64-bit UST
   2678  * \returns Zero on success or a negative errno value on failure.
   2679  *
   2680  * \sa glXGetProcAddress, PFNGLXGETUSTPROC
   2681  *
   2682  * \since Internal API version 20030317.
   2683  */
   2684 _X_HIDDEN int
   2685 __glXGetUST(int64_t * ust)
   2686 {
   2687    struct timeval tv;
   2688 
   2689    if (ust == NULL) {
   2690       return -EFAULT;
   2691    }
   2692 
   2693    if (gettimeofday(&tv, NULL) == 0) {
   2694       ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
   2695       return 0;
   2696    }
   2697    else {
   2698       return -errno;
   2699    }
   2700 }
   2701 #endif /* GLX_DIRECT_RENDERING */
   2702 
   2703 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
   2704 
   2705 PUBLIC int
   2706 MesaGLInteropGLXQueryDeviceInfo(Display *dpy, GLXContext context,
   2707                                 struct mesa_glinterop_device_info *out)
   2708 {
   2709    struct glx_context *gc = (struct glx_context*)context;
   2710    int ret;
   2711 
   2712    __glXLock();
   2713 
   2714    if (!gc || gc->xid == None || !gc->isDirect) {
   2715       __glXUnlock();
   2716       return MESA_GLINTEROP_INVALID_CONTEXT;
   2717    }
   2718 
   2719    if (!gc->vtable->interop_query_device_info) {
   2720       __glXUnlock();
   2721       return MESA_GLINTEROP_UNSUPPORTED;
   2722    }
   2723 
   2724    ret = gc->vtable->interop_query_device_info(gc, out);
   2725    __glXUnlock();
   2726    return ret;
   2727 }
   2728 
   2729 PUBLIC int
   2730 MesaGLInteropGLXExportObject(Display *dpy, GLXContext context,
   2731                              struct mesa_glinterop_export_in *in,
   2732                              struct mesa_glinterop_export_out *out)
   2733 {
   2734    struct glx_context *gc = (struct glx_context*)context;
   2735    int ret;
   2736 
   2737    __glXLock();
   2738 
   2739    if (!gc || gc->xid == None || !gc->isDirect) {
   2740       __glXUnlock();
   2741       return MESA_GLINTEROP_INVALID_CONTEXT;
   2742    }
   2743 
   2744    if (!gc->vtable->interop_export_object) {
   2745       __glXUnlock();
   2746       return MESA_GLINTEROP_UNSUPPORTED;
   2747    }
   2748 
   2749    ret = gc->vtable->interop_export_object(gc, in, out);
   2750    __glXUnlock();
   2751    return ret;
   2752 }
   2753 
   2754 #endif /* defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) */
   2755