Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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