Subversion Repositories Kolibri OS

Rev

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