Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  5.  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * 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.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23.  * OTHER DEALINGS IN THE SOFTWARE.
  24.  */
  25.  
  26.  
  27. /**
  28.  * "Fake" GLX API implemented in terms of the XMesa*() functions.
  29.  */
  30.  
  31.  
  32.  
  33. #define GLX_GLXEXT_PROTOTYPES
  34. #include "GL/glx.h"
  35.  
  36. #include "xm_api.h"
  37.  
  38.  
  39. /* This indicates the client-side GLX API and GLX encoder version. */
  40. #define CLIENT_MAJOR_VERSION 1
  41. #define CLIENT_MINOR_VERSION 4  /* but don't have 1.3's pbuffers, etc yet */
  42.  
  43. /* This indicates the server-side GLX decoder version.
  44.  * GLX 1.4 indicates OpenGL 1.3 support
  45.  */
  46. #define SERVER_MAJOR_VERSION 1
  47. #define SERVER_MINOR_VERSION 4
  48.  
  49. /* Who implemented this GLX? */
  50. #define VENDOR "Brian Paul"
  51.  
  52. #define EXTENSIONS \
  53.    "GLX_MESA_copy_sub_buffer " \
  54.    "GLX_MESA_pixmap_colormap " \
  55.    "GLX_MESA_release_buffers " \
  56.    "GLX_ARB_create_context " \
  57.    "GLX_ARB_create_context_profile " \
  58.    "GLX_ARB_get_proc_address " \
  59.    "GLX_EXT_texture_from_pixmap " \
  60.    "GLX_EXT_visual_info " \
  61.    "GLX_EXT_visual_rating " \
  62.    /*"GLX_SGI_video_sync "*/ \
  63.    "GLX_SGIX_fbconfig " \
  64.    "GLX_SGIX_pbuffer "
  65.  
  66. #define DEFAULT_DIRECT GL_TRUE
  67.  
  68.  
  69. /** XXX this could be based on gallium's max texture size */
  70. #define PBUFFER_MAX_SIZE 16384
  71.  
  72.  
  73. /**
  74.  * The GLXContext typedef is defined as a pointer to this structure.
  75.  */
  76. struct __GLXcontextRec
  77. {
  78.    Display *currentDpy;
  79.    GLboolean isDirect;
  80.    GLXDrawable currentDrawable;
  81.    GLXDrawable currentReadable;
  82.    XID xid;
  83.  
  84.    XMesaContext xmesaContext;
  85. };
  86.  
  87.  
  88.  
  89. static pipe_tsd ContextTSD;
  90.  
  91. /** Set current context for calling thread */
  92. static void
  93. SetCurrentContext(GLXContext c)
  94. {
  95.    pipe_tsd_set(&ContextTSD, c);
  96. }
  97.  
  98. /** Get current context for calling thread */
  99. static GLXContext
  100. GetCurrentContext(void)
  101. {
  102.    return pipe_tsd_get(&ContextTSD);
  103. }
  104.  
  105.  
  106.  
  107. /**********************************************************************/
  108. /***                       GLX Visual Code                          ***/
  109. /**********************************************************************/
  110.  
  111. #define DONT_CARE -1
  112.  
  113.  
  114. static XMesaVisual *VisualTable = NULL;
  115. static int NumVisuals = 0;
  116.  
  117.  
  118.  
  119. /* Macro to handle c_class vs class field name in XVisualInfo struct */
  120. #if defined(__cplusplus) || defined(c_plusplus)
  121. #define CLASS c_class
  122. #else
  123. #define CLASS class
  124. #endif
  125.  
  126.  
  127.  
  128. /*
  129.  * Test if the given XVisualInfo is usable for Mesa rendering.
  130.  */
  131. static GLboolean
  132. is_usable_visual( XVisualInfo *vinfo )
  133. {
  134.    switch (vinfo->CLASS) {
  135.       case StaticGray:
  136.       case GrayScale:
  137.          /* Any StaticGray/GrayScale visual works in RGB or CI mode */
  138.          return GL_TRUE;
  139.       case StaticColor:
  140.       case PseudoColor:
  141.          /* Any StaticColor/PseudoColor visual of at least 4 bits */
  142.          if (vinfo->depth>=4) {
  143.             return GL_TRUE;
  144.          }
  145.          else {
  146.             return GL_FALSE;
  147.          }
  148.       case TrueColor:
  149.       case DirectColor:
  150.          /* Any depth of TrueColor or DirectColor works in RGB mode */
  151.          return GL_TRUE;
  152.       default:
  153.          /* This should never happen */
  154.          return GL_FALSE;
  155.    }
  156. }
  157.  
  158.  
  159. /*
  160.  * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
  161.  * configuration in our list of GLX visuals.
  162.  */
  163. static XMesaVisual
  164. save_glx_visual( Display *dpy, XVisualInfo *vinfo,
  165.                  GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
  166.                  GLboolean stereoFlag,
  167.                  GLint depth_size, GLint stencil_size,
  168.                  GLint accumRedSize, GLint accumGreenSize,
  169.                  GLint accumBlueSize, GLint accumAlphaSize,
  170.                  GLint level, GLint numAuxBuffers )
  171. {
  172.    GLboolean ximageFlag = GL_TRUE;
  173.    XMesaVisual xmvis;
  174.    GLint i;
  175.    GLboolean comparePointers;
  176.  
  177.    if (dbFlag) {
  178.       /* Check if the MESA_BACK_BUFFER env var is set */
  179.       char *backbuffer = _mesa_getenv("MESA_BACK_BUFFER");
  180.       if (backbuffer) {
  181.          if (backbuffer[0]=='p' || backbuffer[0]=='P') {
  182.             ximageFlag = GL_FALSE;
  183.          }
  184.          else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
  185.             ximageFlag = GL_TRUE;
  186.          }
  187.          else {
  188.             _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage.");
  189.          }
  190.       }
  191.    }
  192.  
  193.    if (stereoFlag) {
  194.       /* stereo not supported */
  195.       return NULL;
  196.    }
  197.  
  198.    if (stencil_size > 0 && depth_size > 0)
  199.       depth_size = 24;
  200.  
  201.    /* Comparing IDs uses less memory but sometimes fails. */
  202.    /* XXX revisit this after 3.0 is finished. */
  203.    if (_mesa_getenv("MESA_GLX_VISUAL_HACK"))
  204.       comparePointers = GL_TRUE;
  205.    else
  206.       comparePointers = GL_FALSE;
  207.  
  208.    /* Force the visual to have an alpha channel */
  209.    if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA"))
  210.       alphaFlag = GL_TRUE;
  211.  
  212.    /* First check if a matching visual is already in the list */
  213.    for (i=0; i<NumVisuals; i++) {
  214.       XMesaVisual v = VisualTable[i];
  215.       if (v->display == dpy
  216.           && v->mesa_visual.level == level
  217.           && v->mesa_visual.numAuxBuffers == numAuxBuffers
  218.           && v->ximage_flag == ximageFlag
  219.           && v->mesa_visual.rgbMode == rgbFlag
  220.           && v->mesa_visual.doubleBufferMode == dbFlag
  221.           && v->mesa_visual.stereoMode == stereoFlag
  222.           && (v->mesa_visual.alphaBits > 0) == alphaFlag
  223.           && (v->mesa_visual.depthBits >= depth_size || depth_size == 0)
  224.           && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0)
  225.           && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0)
  226.           && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0)
  227.           && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0)
  228.           && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) {
  229.          /* now either compare XVisualInfo pointers or visual IDs */
  230.          if ((!comparePointers && v->visinfo->visualid == vinfo->visualid)
  231.              || (comparePointers && v->vishandle == vinfo)) {
  232.             return v;
  233.          }
  234.       }
  235.    }
  236.  
  237.    /* Create a new visual and add it to the list. */
  238.  
  239.    xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
  240.                               stereoFlag, ximageFlag,
  241.                               depth_size, stencil_size,
  242.                               accumRedSize, accumBlueSize,
  243.                               accumBlueSize, accumAlphaSize, 0, level,
  244.                               GLX_NONE_EXT );
  245.    if (xmvis) {
  246.       /* Save a copy of the pointer now so we can find this visual again
  247.        * if we need to search for it in find_glx_visual().
  248.        */
  249.       xmvis->vishandle = vinfo;
  250.       /* Allocate more space for additional visual */
  251.       VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable,
  252.                                    sizeof(XMesaVisual) * NumVisuals,
  253.                                    sizeof(XMesaVisual) * (NumVisuals + 1));
  254.       /* add xmvis to the list */
  255.       VisualTable[NumVisuals] = xmvis;
  256.       NumVisuals++;
  257.       /* XXX minor hack, because XMesaCreateVisual doesn't support an
  258.        * aux buffers parameter.
  259.        */
  260.       xmvis->mesa_visual.numAuxBuffers = numAuxBuffers;
  261.    }
  262.    return xmvis;
  263. }
  264.  
  265.  
  266. /**
  267.  * Return the default number of bits for the Z buffer.
  268.  * If defined, use the MESA_GLX_DEPTH_BITS env var value.
  269.  * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant.
  270.  * XXX probably do the same thing for stencil, accum, etc.
  271.  */
  272. static GLint
  273. default_depth_bits(void)
  274. {
  275.    int zBits;
  276.    const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS");
  277.    if (zEnv)
  278.       zBits = atoi(zEnv);
  279.    else
  280.       zBits = 24;
  281.    return zBits;
  282. }
  283.  
  284. static GLint
  285. default_alpha_bits(void)
  286. {
  287.    int aBits;
  288.    const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS");
  289.    if (aEnv)
  290.       aBits = atoi(aEnv);
  291.    else
  292.       aBits = 0;
  293.    return aBits;
  294. }
  295.  
  296. static GLint
  297. default_accum_bits(void)
  298. {
  299.    return 16;
  300. }
  301.  
  302.  
  303.  
  304. /*
  305.  * Create a GLX visual from a regular XVisualInfo.
  306.  * This is called when Fake GLX is given an XVisualInfo which wasn't
  307.  * returned by glXChooseVisual.  Since this is the first time we're
  308.  * considering this visual we'll take a guess at reasonable values
  309.  * for depth buffer size, stencil size, accum size, etc.
  310.  * This is the best we can do with a client-side emulation of GLX.
  311.  */
  312. static XMesaVisual
  313. create_glx_visual( Display *dpy, XVisualInfo *visinfo )
  314. {
  315.    GLint zBits = default_depth_bits();
  316.    GLint accBits = default_accum_bits();
  317.    GLboolean alphaFlag = default_alpha_bits() > 0;
  318.  
  319.    if (is_usable_visual( visinfo )) {
  320.       /* Configure this visual as RGB, double-buffered, depth-buffered. */
  321.       /* This is surely wrong for some people's needs but what else */
  322.       /* can be done?  They should use glXChooseVisual(). */
  323.       return save_glx_visual( dpy, visinfo,
  324.                               GL_TRUE,   /* rgb */
  325.                               alphaFlag, /* alpha */
  326.                               GL_TRUE,   /* double */
  327.                               GL_FALSE,  /* stereo */
  328.                               zBits,
  329.                               8,       /* stencil bits */
  330.                               accBits, /* r */
  331.                               accBits, /* g */
  332.                               accBits, /* b */
  333.                               accBits, /* a */
  334.                               0,         /* level */
  335.                               0          /* numAux */
  336.          );
  337.    }
  338.    else {
  339.       _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n");
  340.       return NULL;
  341.    }
  342. }
  343.  
  344.  
  345.  
  346. /*
  347.  * Find the GLX visual associated with an XVisualInfo.
  348.  */
  349. static XMesaVisual
  350. find_glx_visual( Display *dpy, XVisualInfo *vinfo )
  351. {
  352.    int i;
  353.  
  354.    /* try to match visual id */
  355.    for (i=0;i<NumVisuals;i++) {
  356.       if (VisualTable[i]->display==dpy
  357.           && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
  358.          return VisualTable[i];
  359.       }
  360.    }
  361.  
  362.    /* if that fails, try to match pointers */
  363.    for (i=0;i<NumVisuals;i++) {
  364.       if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
  365.          return VisualTable[i];
  366.       }
  367.    }
  368.  
  369.    return NULL;
  370. }
  371.  
  372.  
  373. /**
  374.  * Try to get an X visual which matches the given arguments.
  375.  */
  376. static XVisualInfo *
  377. get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
  378. {
  379.    XVisualInfo temp, *vis;
  380.    long mask;
  381.    int n;
  382.    unsigned int default_depth;
  383.    int default_class;
  384.  
  385.    mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
  386.    temp.screen = scr;
  387.    temp.depth = depth;
  388.    temp.CLASS = xclass;
  389.  
  390.    default_depth = DefaultDepth(dpy,scr);
  391.    default_class = DefaultVisual(dpy,scr)->CLASS;
  392.  
  393.    if (depth==default_depth && xclass==default_class) {
  394.       /* try to get root window's visual */
  395.       temp.visualid = DefaultVisual(dpy,scr)->visualid;
  396.       mask |= VisualIDMask;
  397.    }
  398.  
  399.    vis = XGetVisualInfo( dpy, mask, &temp, &n );
  400.  
  401.    /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
  402.     * An SGI Infinite Reality system, for example, can have 30bpp pixels:
  403.     * 10 bits per color channel.  Mesa's limited to a max of 8 bits/channel.
  404.     */
  405.    if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
  406.       if (_mesa_bitcount((GLuint) vis->red_mask  ) <= 8 &&
  407.           _mesa_bitcount((GLuint) vis->green_mask) <= 8 &&
  408.           _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) {
  409.          return vis;
  410.       }
  411.       else {
  412.          free((void *) vis);
  413.          return NULL;
  414.       }
  415.    }
  416.    
  417.    return vis;
  418. }
  419.  
  420.  
  421. /*
  422.  * Retrieve the value of the given environment variable and find
  423.  * the X visual which matches it.
  424.  * Input:  dpy - the display
  425.  *         screen - the screen number
  426.  *         varname - the name of the environment variable
  427.  * Return:  an XVisualInfo pointer to NULL if error.
  428.  */
  429. static XVisualInfo *
  430. get_env_visual(Display *dpy, int scr, const char *varname)
  431. {
  432.    char value[100], type[100];
  433.    int depth, xclass = -1;
  434.    XVisualInfo *vis;
  435.  
  436.    if (!_mesa_getenv( varname )) {
  437.       return NULL;
  438.    }
  439.  
  440.    strncpy( value, _mesa_getenv(varname), 100 );
  441.    value[99] = 0;
  442.  
  443.    sscanf( value, "%s %d", type, &depth );
  444.  
  445.    if (strcmp(type,"TrueColor")==0)          xclass = TrueColor;
  446.    else if (strcmp(type,"DirectColor")==0)   xclass = DirectColor;
  447.    else if (strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
  448.    else if (strcmp(type,"StaticColor")==0)   xclass = StaticColor;
  449.    else if (strcmp(type,"GrayScale")==0)     xclass = GrayScale;
  450.    else if (strcmp(type,"StaticGray")==0)    xclass = StaticGray;
  451.  
  452.    if (xclass>-1 && depth>0) {
  453.       vis = get_visual( dpy, scr, depth, xclass );
  454.       if (vis) {
  455.          return vis;
  456.       }
  457.    }
  458.  
  459.    _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.",
  460.                  type, depth);
  461.  
  462.    return NULL;
  463. }
  464.  
  465.  
  466.  
  467. /*
  468.  * Select an X visual which satisfies the RGBA flag and minimum depth.
  469.  * Input:  dpy,
  470.  *         screen - X display and screen number
  471.  *         min_depth - minimum visual depth
  472.  *         preferred_class - preferred GLX visual class or DONT_CARE
  473.  * Return:  pointer to an XVisualInfo or NULL.
  474.  */
  475. static XVisualInfo *
  476. choose_x_visual( Display *dpy, int screen, int min_depth,
  477.                  int preferred_class )
  478. {
  479.    XVisualInfo *vis;
  480.    int xclass, visclass = 0;
  481.    int depth;
  482.  
  483.    /* First see if the MESA_RGB_VISUAL env var is defined */
  484.    vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
  485.    if (vis) {
  486.       return vis;
  487.    }
  488.    /* Otherwise, search for a suitable visual */
  489.    if (preferred_class==DONT_CARE) {
  490.       for (xclass=0;xclass<6;xclass++) {
  491.          switch (xclass) {
  492.          case 0:  visclass = TrueColor;    break;
  493.          case 1:  visclass = DirectColor;  break;
  494.          case 2:  visclass = PseudoColor;  break;
  495.          case 3:  visclass = StaticColor;  break;
  496.          case 4:  visclass = GrayScale;    break;
  497.          case 5:  visclass = StaticGray;   break;
  498.          }
  499.          if (min_depth==0) {
  500.             /* start with shallowest */
  501.             for (depth=0;depth<=32;depth++) {
  502.                if (visclass==TrueColor && depth==8) {
  503.                   /* Special case:  try to get 8-bit PseudoColor before */
  504.                   /* 8-bit TrueColor */
  505.                   vis = get_visual( dpy, screen, 8, PseudoColor );
  506.                   if (vis) {
  507.                      return vis;
  508.                   }
  509.                }
  510.                vis = get_visual( dpy, screen, depth, visclass );
  511.                if (vis) {
  512.                   return vis;
  513.                }
  514.             }
  515.          }
  516.          else {
  517.             /* start with deepest */
  518.             for (depth=32;depth>=min_depth;depth--) {
  519.                if (visclass==TrueColor && depth==8) {
  520.                   /* Special case:  try to get 8-bit PseudoColor before */
  521.                   /* 8-bit TrueColor */
  522.                   vis = get_visual( dpy, screen, 8, PseudoColor );
  523.                   if (vis) {
  524.                      return vis;
  525.                   }
  526.                }
  527.                vis = get_visual( dpy, screen, depth, visclass );
  528.                if (vis) {
  529.                   return vis;
  530.                }
  531.             }
  532.          }
  533.       }
  534.    }
  535.    else {
  536.       /* search for a specific visual class */
  537.       switch (preferred_class) {
  538.       case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
  539.       case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
  540.       case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
  541.       case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
  542.       case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
  543.       case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
  544.       default:   return NULL;
  545.       }
  546.       if (min_depth==0) {
  547.          /* start with shallowest */
  548.          for (depth=0;depth<=32;depth++) {
  549.             vis = get_visual( dpy, screen, depth, visclass );
  550.             if (vis) {
  551.                return vis;
  552.             }
  553.          }
  554.       }
  555.       else {
  556.          /* start with deepest */
  557.          for (depth=32;depth>=min_depth;depth--) {
  558.             vis = get_visual( dpy, screen, depth, visclass );
  559.             if (vis) {
  560.                return vis;
  561.             }
  562.          }
  563.       }
  564.    }
  565.  
  566.    /* didn't find a visual */
  567.    return NULL;
  568. }
  569.  
  570.  
  571.  
  572.  
  573. /**********************************************************************/
  574. /***             Display-related functions                          ***/
  575. /**********************************************************************/
  576.  
  577.  
  578. /**
  579.  * Free all XMesaVisuals which are associated with the given display.
  580.  */
  581. static void
  582. destroy_visuals_on_display(Display *dpy)
  583. {
  584.    int i;
  585.    for (i = 0; i < NumVisuals; i++) {
  586.       if (VisualTable[i]->display == dpy) {
  587.          /* remove this visual */
  588.          int j;
  589.          free(VisualTable[i]);
  590.          for (j = i; j < NumVisuals - 1; j++)
  591.             VisualTable[j] = VisualTable[j + 1];
  592.          NumVisuals--;
  593.       }
  594.    }
  595. }
  596.  
  597.  
  598. /**
  599.  * Called from XCloseDisplay() to let us free our display-related data.
  600.  */
  601. static int
  602. close_display_callback(Display *dpy, XExtCodes *codes)
  603. {
  604.    xmesa_destroy_buffers_on_display(dpy);
  605.    destroy_visuals_on_display(dpy);
  606.    return 0;
  607. }
  608.  
  609.  
  610. /**
  611.  * Look for the named extension on given display and return a pointer
  612.  * to the _XExtension data, or NULL if extension not found.
  613.  */
  614. static _XExtension *
  615. lookup_extension(Display *dpy, const char *extName)
  616. {
  617.    _XExtension *ext;
  618.    for (ext = dpy->ext_procs; ext; ext = ext->next) {
  619.       if (ext->name && strcmp(ext->name, extName) == 0) {
  620.          return ext;
  621.       }
  622.    }
  623.    return NULL;
  624. }
  625.  
  626.  
  627. /**
  628.  * Whenever we're given a new Display pointer, call this function to
  629.  * register our close_display_callback function.
  630.  */
  631. static void
  632. register_with_display(Display *dpy)
  633. {
  634.    const char *extName = "MesaGLX";
  635.    _XExtension *ext;
  636.  
  637.    ext = lookup_extension(dpy, extName);
  638.    if (!ext) {
  639.       XExtCodes *c = XAddExtension(dpy);
  640.       ext = dpy->ext_procs;  /* new extension is at head of list */
  641.       assert(c->extension == ext->codes.extension);
  642.       (void) c;
  643.       ext->name = _mesa_strdup(extName);
  644.       ext->close_display = close_display_callback;
  645.    }
  646. }
  647.  
  648.  
  649. /**********************************************************************/
  650. /***                  Begin Fake GLX API Functions                  ***/
  651. /**********************************************************************/
  652.  
  653.  
  654. /**
  655.  * Helper used by glXChooseVisual and glXChooseFBConfig.
  656.  * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for
  657.  * the later.
  658.  * In either case, the attribute list is terminated with the value 'None'.
  659.  */
  660. static XMesaVisual
  661. choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
  662. {
  663.    const GLboolean rgbModeDefault = fbConfig;
  664.    const int *parselist;
  665.    XVisualInfo *vis;
  666.    int min_red=0, min_green=0, min_blue=0;
  667.    GLboolean rgb_flag = rgbModeDefault;
  668.    GLboolean alpha_flag = GL_FALSE;
  669.    GLboolean double_flag = GL_FALSE;
  670.    GLboolean stereo_flag = GL_FALSE;
  671.    GLint depth_size = 0;
  672.    GLint stencil_size = 0;
  673.    GLint accumRedSize = 0;
  674.    GLint accumGreenSize = 0;
  675.    GLint accumBlueSize = 0;
  676.    GLint accumAlphaSize = 0;
  677.    int level = 0;
  678.    int visual_type = DONT_CARE;
  679.    GLint caveat = DONT_CARE;
  680.    XMesaVisual xmvis = NULL;
  681.    int desiredVisualID = -1;
  682.    int numAux = 0;
  683.  
  684.    xmesa_init( dpy );
  685.  
  686.    parselist = list;
  687.  
  688.    while (*parselist) {
  689.  
  690.       if (fbConfig &&
  691.           parselist[1] == GLX_DONT_CARE &&
  692.           parselist[0] != GLX_LEVEL) {
  693.          /* For glXChooseFBConfig(), skip attributes whose value is
  694.           * GLX_DONT_CARE, unless it's GLX_LEVEL (which can legitimately be
  695.           * a negative value).
  696.           *
  697.           * From page 17 (23 of the pdf) of the GLX 1.4 spec:
  698.           * GLX DONT CARE may be specified for all attributes except GLX LEVEL.
  699.           */
  700.          parselist += 2;
  701.          continue;
  702.       }
  703.  
  704.       switch (*parselist) {
  705.          case GLX_USE_GL:
  706.             if (fbConfig) {
  707.                /* invalid token */
  708.                return NULL;
  709.             }
  710.             else {
  711.                /* skip */
  712.                parselist++;
  713.             }
  714.             break;
  715.          case GLX_BUFFER_SIZE:
  716.             parselist++;
  717.             parselist++;
  718.             break;
  719.          case GLX_LEVEL:
  720.             parselist++;
  721.             level = *parselist++;
  722.             break;
  723.          case GLX_RGBA:
  724.             if (fbConfig) {
  725.                /* invalid token */
  726.                return NULL;
  727.             }
  728.             else {
  729.                rgb_flag = GL_TRUE;
  730.                parselist++;
  731.             }
  732.             break;
  733.          case GLX_DOUBLEBUFFER:
  734.             parselist++;
  735.             if (fbConfig) {
  736.                double_flag = *parselist++;
  737.             }
  738.             else {
  739.                double_flag = GL_TRUE;
  740.             }
  741.             break;
  742.          case GLX_STEREO:
  743.             parselist++;
  744.             if (fbConfig) {
  745.                stereo_flag = *parselist++;
  746.             }
  747.             else {
  748.                stereo_flag = GL_TRUE;
  749.             }
  750.             break;
  751.          case GLX_AUX_BUFFERS:
  752.             parselist++;
  753.             numAux = *parselist++;
  754.             if (numAux > MAX_AUX_BUFFERS)
  755.                return NULL;
  756.             break;
  757.          case GLX_RED_SIZE:
  758.             parselist++;
  759.             min_red = *parselist++;
  760.             break;
  761.          case GLX_GREEN_SIZE:
  762.             parselist++;
  763.             min_green = *parselist++;
  764.             break;
  765.          case GLX_BLUE_SIZE:
  766.             parselist++;
  767.             min_blue = *parselist++;
  768.             break;
  769.          case GLX_ALPHA_SIZE:
  770.             parselist++;
  771.             {
  772.                GLint size = *parselist++;
  773.                alpha_flag = size ? GL_TRUE : GL_FALSE;
  774.             }
  775.             break;
  776.          case GLX_DEPTH_SIZE:
  777.             parselist++;
  778.             depth_size = *parselist++;
  779.             break;
  780.          case GLX_STENCIL_SIZE:
  781.             parselist++;
  782.             stencil_size = *parselist++;
  783.             break;
  784.          case GLX_ACCUM_RED_SIZE:
  785.             parselist++;
  786.             {
  787.                GLint size = *parselist++;
  788.                accumRedSize = MAX2( accumRedSize, size );
  789.             }
  790.             break;
  791.          case GLX_ACCUM_GREEN_SIZE:
  792.             parselist++;
  793.             {
  794.                GLint size = *parselist++;
  795.                accumGreenSize = MAX2( accumGreenSize, size );
  796.             }
  797.             break;
  798.          case GLX_ACCUM_BLUE_SIZE:
  799.             parselist++;
  800.             {
  801.                GLint size = *parselist++;
  802.                accumBlueSize = MAX2( accumBlueSize, size );
  803.             }
  804.             break;
  805.          case GLX_ACCUM_ALPHA_SIZE:
  806.             parselist++;
  807.             {
  808.                GLint size = *parselist++;
  809.                accumAlphaSize = MAX2( accumAlphaSize, size );
  810.             }
  811.             break;
  812.  
  813.          /*
  814.           * GLX_EXT_visual_info extension
  815.           */
  816.          case GLX_X_VISUAL_TYPE_EXT:
  817.             parselist++;
  818.             visual_type = *parselist++;
  819.             break;
  820.          case GLX_TRANSPARENT_TYPE_EXT:
  821.             parselist++;
  822.             parselist++;
  823.             break;
  824.          case GLX_TRANSPARENT_INDEX_VALUE_EXT:
  825.             parselist++;
  826.             parselist++;
  827.             break;
  828.          case GLX_TRANSPARENT_RED_VALUE_EXT:
  829.          case GLX_TRANSPARENT_GREEN_VALUE_EXT:
  830.          case GLX_TRANSPARENT_BLUE_VALUE_EXT:
  831.          case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
  832.             /* ignore */
  833.             parselist++;
  834.             parselist++;
  835.             break;
  836.  
  837.          /*
  838.           * GLX_EXT_visual_info extension
  839.           */
  840.          case GLX_VISUAL_CAVEAT_EXT:
  841.             parselist++;
  842.             caveat = *parselist++; /* ignored for now */
  843.             break;
  844.  
  845.          /*
  846.           * GLX_ARB_multisample
  847.           */
  848.          case GLX_SAMPLE_BUFFERS_ARB:
  849.          case GLX_SAMPLES_ARB:
  850.             parselist++;
  851.             if (*parselist++ != 0) {
  852.                /* ms not supported */
  853.                return NULL;
  854.             }
  855.             break;
  856.  
  857.          /*
  858.           * FBConfig attribs.
  859.           */
  860.          case GLX_RENDER_TYPE:
  861.             if (!fbConfig)
  862.                return NULL;
  863.             parselist++;
  864.             if (*parselist & GLX_RGBA_BIT) {
  865.                rgb_flag = GL_TRUE;
  866.             }
  867.             else if (*parselist & GLX_COLOR_INDEX_BIT) {
  868.                rgb_flag = GL_FALSE;
  869.             }
  870.             else if (*parselist == 0) {
  871.                rgb_flag = GL_TRUE;
  872.             }
  873.             parselist++;
  874.             break;
  875.          case GLX_DRAWABLE_TYPE:
  876.             if (!fbConfig)
  877.                return NULL;
  878.             parselist++;
  879.             if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) {
  880.                return NULL; /* bad bit */
  881.             }
  882.             parselist++;
  883.             break;
  884.          case GLX_FBCONFIG_ID:
  885.          case GLX_VISUAL_ID:
  886.             if (!fbConfig)
  887.                return NULL;
  888.             parselist++;
  889.             desiredVisualID = *parselist++;
  890.             break;
  891.          case GLX_X_RENDERABLE:
  892.          case GLX_MAX_PBUFFER_WIDTH:
  893.          case GLX_MAX_PBUFFER_HEIGHT:
  894.          case GLX_MAX_PBUFFER_PIXELS:
  895.             if (!fbConfig)
  896.                return NULL; /* invalid config option */
  897.             parselist += 2; /* ignore the parameter */
  898.             break;
  899.  
  900. #ifdef GLX_EXT_texture_from_pixmap
  901.          case GLX_BIND_TO_TEXTURE_RGB_EXT:
  902.             parselist++; /*skip*/
  903.             break;
  904.          case GLX_BIND_TO_TEXTURE_RGBA_EXT:
  905.             parselist++; /*skip*/
  906.             break;
  907.          case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
  908.             parselist++; /*skip*/
  909.             break;
  910.          case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
  911.             parselist++;
  912.             if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT |
  913.                                GLX_TEXTURE_2D_BIT_EXT |
  914.                                GLX_TEXTURE_RECTANGLE_BIT_EXT)) {
  915.                /* invalid bit */
  916.                return NULL;
  917.             }
  918.             break;
  919.          case GLX_Y_INVERTED_EXT:
  920.             parselist++; /*skip*/
  921.             break;
  922. #endif
  923.  
  924.          case None:
  925.             /* end of list */
  926.             break;
  927.  
  928.          default:
  929.             /* undefined attribute */
  930.             _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()",
  931.                           *parselist);
  932.             return NULL;
  933.       }
  934.    }
  935.  
  936.    (void) caveat;
  937.  
  938.  
  939.    /*
  940.     * Since we're only simulating the GLX extension this function will never
  941.     * find any real GL visuals.  Instead, all we can do is try to find an RGB
  942.     * or CI visual of appropriate depth.  Other requested attributes such as
  943.     * double buffering, depth buffer, etc. will be associated with the X
  944.     * visual and stored in the VisualTable[].
  945.     */
  946.    if (desiredVisualID != -1) {
  947.       /* try to get a specific visual, by visualID */
  948.       XVisualInfo temp;
  949.       int n;
  950.       temp.visualid = desiredVisualID;
  951.       temp.screen = screen;
  952.       vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n);
  953.       if (vis) {
  954.          /* give the visual some useful GLX attributes */
  955.          double_flag = GL_TRUE;
  956.          rgb_flag = GL_TRUE;
  957.       }
  958.    }
  959.    else if (level==0) {
  960.       /* normal color planes */
  961.       /* Get an RGB visual */
  962.       int min_rgb = min_red + min_green + min_blue;
  963.       if (min_rgb>1 && min_rgb<8) {
  964.          /* a special case to be sure we can get a monochrome visual */
  965.          min_rgb = 1;
  966.       }
  967.       vis = choose_x_visual( dpy, screen, min_rgb, visual_type );
  968.    }
  969.    else {
  970.       _mesa_warning(NULL, "overlay not supported");
  971.       return NULL;
  972.    }
  973.  
  974.    if (vis) {
  975.       /* Note: we're not exactly obeying the glXChooseVisual rules here.
  976.        * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
  977.        * largest depth buffer size, which is 32bits/value.  Instead, we
  978.        * return 16 to maintain performance with earlier versions of Mesa.
  979.        */
  980.       if (stencil_size > 0)
  981.          depth_size = 24;  /* if Z and stencil, always use 24+8 format */
  982.       else if (depth_size > 24)
  983.          depth_size = 32;
  984.       else if (depth_size > 16)
  985.          depth_size = 24;
  986.       else if (depth_size > 0) {
  987.          depth_size = default_depth_bits();
  988.       }
  989.  
  990.       if (!alpha_flag) {
  991.          alpha_flag = default_alpha_bits() > 0;
  992.       }
  993.  
  994.       /* we only support one size of stencil and accum buffers. */
  995.       if (stencil_size > 0)
  996.          stencil_size = 8;
  997.  
  998.       if (accumRedSize > 0 ||
  999.           accumGreenSize > 0 ||
  1000.           accumBlueSize > 0 ||
  1001.           accumAlphaSize > 0) {
  1002.  
  1003.          accumRedSize =
  1004.             accumGreenSize =
  1005.             accumBlueSize = default_accum_bits();
  1006.  
  1007.          accumAlphaSize = alpha_flag ? accumRedSize : 0;
  1008.       }
  1009.  
  1010.       xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
  1011.                                stereo_flag, depth_size, stencil_size,
  1012.                                accumRedSize, accumGreenSize,
  1013.                                accumBlueSize, accumAlphaSize, level, numAux );
  1014.    }
  1015.  
  1016.    return xmvis;
  1017. }
  1018.  
  1019.  
  1020. PUBLIC XVisualInfo *
  1021. glXChooseVisual( Display *dpy, int screen, int *list )
  1022. {
  1023.    XMesaVisual xmvis;
  1024.  
  1025.    /* register ourselves as an extension on this display */
  1026.    register_with_display(dpy);
  1027.  
  1028.    xmvis = choose_visual(dpy, screen, list, GL_FALSE);
  1029.    if (xmvis) {
  1030.       /* create a new vishandle - the cached one may be stale */
  1031.       xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo));
  1032.       if (xmvis->vishandle) {
  1033.          memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
  1034.       }
  1035.       return xmvis->vishandle;
  1036.    }
  1037.    else
  1038.       return NULL;
  1039. }
  1040.  
  1041.  
  1042. /**
  1043.  * Helper function used by other glXCreateContext functions.
  1044.  */
  1045. static GLXContext
  1046. create_context(Display *dpy, XMesaVisual xmvis,
  1047.                XMesaContext shareCtx, Bool direct,
  1048.                unsigned major, unsigned minor,
  1049.                unsigned profileMask, unsigned contextFlags)
  1050. {
  1051.    GLXContext glxCtx;
  1052.  
  1053.    if (!dpy || !xmvis)
  1054.       return 0;
  1055.  
  1056.    glxCtx = CALLOC_STRUCT(__GLXcontextRec);
  1057.    if (!glxCtx)
  1058.       return 0;
  1059.  
  1060.    /* deallocate unused windows/buffers */
  1061. #if 0
  1062.    XMesaGarbageCollect();
  1063. #endif
  1064.  
  1065.    glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx, major, minor,
  1066.                                              profileMask, contextFlags);
  1067.    if (!glxCtx->xmesaContext) {
  1068.       free(glxCtx);
  1069.       return NULL;
  1070.    }
  1071.  
  1072.    glxCtx->isDirect = DEFAULT_DIRECT;
  1073.    glxCtx->currentDpy = dpy;
  1074.    glxCtx->xid = (XID) glxCtx;  /* self pointer */
  1075.  
  1076.    return glxCtx;
  1077. }
  1078.  
  1079.  
  1080. PUBLIC GLXContext
  1081. glXCreateContext( Display *dpy, XVisualInfo *visinfo,
  1082.                   GLXContext shareCtx, Bool direct )
  1083. {
  1084.    XMesaVisual xmvis;
  1085.  
  1086.    xmvis = find_glx_visual( dpy, visinfo );
  1087.    if (!xmvis) {
  1088.       /* This visual wasn't found with glXChooseVisual() */
  1089.       xmvis = create_glx_visual( dpy, visinfo );
  1090.       if (!xmvis) {
  1091.          /* unusable visual */
  1092.          return NULL;
  1093.       }
  1094.    }
  1095.  
  1096.    return create_context(dpy, xmvis,
  1097.                          shareCtx ? shareCtx->xmesaContext : NULL,
  1098.                          direct,
  1099.                          1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
  1100. }
  1101.  
  1102.  
  1103. /* XXX these may have to be removed due to thread-safety issues. */
  1104. static GLXContext MakeCurrent_PrevContext = 0;
  1105. static GLXDrawable MakeCurrent_PrevDrawable = 0;
  1106. static GLXDrawable MakeCurrent_PrevReadable = 0;
  1107. static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
  1108. static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
  1109.  
  1110.  
  1111. /* GLX 1.3 and later */
  1112. PUBLIC Bool
  1113. glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
  1114.                        GLXDrawable read, GLXContext ctx )
  1115. {
  1116.    GLXContext glxCtx = ctx;
  1117.    static boolean firsttime = 1, no_rast = 0;
  1118.  
  1119.    if (firsttime) {
  1120.       no_rast = getenv("SP_NO_RAST") != NULL;
  1121.       firsttime = 0;
  1122.    }
  1123.  
  1124.    if (ctx && draw && read) {
  1125.       XMesaBuffer drawBuffer, readBuffer;
  1126.       XMesaContext xmctx = glxCtx->xmesaContext;
  1127.  
  1128.       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
  1129.       if (ctx == MakeCurrent_PrevContext
  1130.           && draw == MakeCurrent_PrevDrawable) {
  1131.          drawBuffer = MakeCurrent_PrevDrawBuffer;
  1132.       }
  1133.       else {
  1134.          drawBuffer = XMesaFindBuffer( dpy, draw );
  1135.       }
  1136.       if (!drawBuffer) {
  1137.          /* drawable must be a new window! */
  1138.          drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
  1139.          if (!drawBuffer) {
  1140.             /* Out of memory, or context/drawable depth mismatch */
  1141.             return False;
  1142.          }
  1143.       }
  1144.  
  1145.       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
  1146.       if (ctx == MakeCurrent_PrevContext
  1147.           && read == MakeCurrent_PrevReadable) {
  1148.          readBuffer = MakeCurrent_PrevReadBuffer;
  1149.       }
  1150.       else {
  1151.          readBuffer = XMesaFindBuffer( dpy, read );
  1152.       }
  1153.       if (!readBuffer) {
  1154.          /* drawable must be a new window! */
  1155.          readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
  1156.          if (!readBuffer) {
  1157.             /* Out of memory, or context/drawable depth mismatch */
  1158.             return False;
  1159.          }
  1160.       }
  1161.  
  1162.       if (no_rast &&
  1163.           MakeCurrent_PrevContext == ctx &&
  1164.           MakeCurrent_PrevDrawable == draw &&
  1165.           MakeCurrent_PrevReadable == read &&
  1166.           MakeCurrent_PrevDrawBuffer == drawBuffer &&
  1167.           MakeCurrent_PrevReadBuffer == readBuffer)
  1168.          return True;
  1169.          
  1170.       MakeCurrent_PrevContext = ctx;
  1171.       MakeCurrent_PrevDrawable = draw;
  1172.       MakeCurrent_PrevReadable = read;
  1173.       MakeCurrent_PrevDrawBuffer = drawBuffer;
  1174.       MakeCurrent_PrevReadBuffer = readBuffer;
  1175.  
  1176.       /* Now make current! */
  1177.       if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
  1178.          ctx->currentDpy = dpy;
  1179.          ctx->currentDrawable = draw;
  1180.          ctx->currentReadable = read;
  1181.          SetCurrentContext(ctx);
  1182.          return True;
  1183.       }
  1184.       else {
  1185.          return False;
  1186.       }
  1187.    }
  1188.    else if (!ctx && !draw && !read) {
  1189.       /* release current context w/out assigning new one. */
  1190.       XMesaMakeCurrent2( NULL, NULL, NULL );
  1191.       MakeCurrent_PrevContext = 0;
  1192.       MakeCurrent_PrevDrawable = 0;
  1193.       MakeCurrent_PrevReadable = 0;
  1194.       MakeCurrent_PrevDrawBuffer = 0;
  1195.       MakeCurrent_PrevReadBuffer = 0;
  1196.       SetCurrentContext(NULL);
  1197.       return True;
  1198.    }
  1199.    else {
  1200.       /* The args must either all be non-zero or all zero.
  1201.        * This is an error.
  1202.        */
  1203.       return False;
  1204.    }
  1205. }
  1206.  
  1207.  
  1208. PUBLIC Bool
  1209. glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
  1210. {
  1211.    return glXMakeContextCurrent( dpy, drawable, drawable, ctx );
  1212. }
  1213.  
  1214.  
  1215. PUBLIC GLXContext
  1216. glXGetCurrentContext(void)
  1217. {
  1218.    return GetCurrentContext();
  1219. }
  1220.  
  1221.  
  1222. PUBLIC Display *
  1223. glXGetCurrentDisplay(void)
  1224. {
  1225.    GLXContext glxCtx = glXGetCurrentContext();
  1226.  
  1227.    return glxCtx ? glxCtx->currentDpy : NULL;
  1228. }
  1229.  
  1230.  
  1231. PUBLIC Display *
  1232. glXGetCurrentDisplayEXT(void)
  1233. {
  1234.    return glXGetCurrentDisplay();
  1235. }
  1236.  
  1237.  
  1238. PUBLIC GLXDrawable
  1239. glXGetCurrentDrawable(void)
  1240. {
  1241.    GLXContext gc = glXGetCurrentContext();
  1242.    return gc ? gc->currentDrawable : 0;
  1243. }
  1244.  
  1245.  
  1246. PUBLIC GLXDrawable
  1247. glXGetCurrentReadDrawable(void)
  1248. {
  1249.    GLXContext gc = glXGetCurrentContext();
  1250.    return gc ? gc->currentReadable : 0;
  1251. }
  1252.  
  1253.  
  1254. PUBLIC GLXDrawable
  1255. glXGetCurrentReadDrawableSGI(void)
  1256. {
  1257.    return glXGetCurrentReadDrawable();
  1258. }
  1259.  
  1260.  
  1261. PUBLIC GLXPixmap
  1262. glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
  1263. {
  1264.    XMesaVisual v;
  1265.    XMesaBuffer b;
  1266.  
  1267.    v = find_glx_visual( dpy, visinfo );
  1268.    if (!v) {
  1269.       v = create_glx_visual( dpy, visinfo );
  1270.       if (!v) {
  1271.          /* unusable visual */
  1272.          return 0;
  1273.       }
  1274.    }
  1275.  
  1276.    b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
  1277.    if (!b) {
  1278.       return 0;
  1279.    }
  1280.    return b->ws.drawable;
  1281. }
  1282.  
  1283.  
  1284. /*** GLX_MESA_pixmap_colormap ***/
  1285.  
  1286. PUBLIC GLXPixmap
  1287. glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
  1288.                         Pixmap pixmap, Colormap cmap )
  1289. {
  1290.    XMesaVisual v;
  1291.    XMesaBuffer b;
  1292.  
  1293.    v = find_glx_visual( dpy, visinfo );
  1294.    if (!v) {
  1295.       v = create_glx_visual( dpy, visinfo );
  1296.       if (!v) {
  1297.          /* unusable visual */
  1298.          return 0;
  1299.       }
  1300.    }
  1301.  
  1302.    b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
  1303.    if (!b) {
  1304.       return 0;
  1305.    }
  1306.    return b->ws.drawable;
  1307. }
  1308.  
  1309.  
  1310. PUBLIC void
  1311. glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
  1312. {
  1313.    XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
  1314.    if (b) {
  1315.       XMesaDestroyBuffer(b);
  1316.    }
  1317.    else if (_mesa_getenv("MESA_DEBUG")) {
  1318.       _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
  1319.    }
  1320. }
  1321.  
  1322.  
  1323. PUBLIC void
  1324. glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
  1325.                 unsigned long mask )
  1326. {
  1327.    XMesaContext xm_src = src->xmesaContext;
  1328.    XMesaContext xm_dst = dst->xmesaContext;
  1329.    (void) dpy;
  1330.    if (MakeCurrent_PrevContext == src) {
  1331.       glFlush();
  1332.    }
  1333.    XMesaCopyContext(xm_src, xm_dst, mask);
  1334. }
  1335.  
  1336.  
  1337. PUBLIC Bool
  1338. glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
  1339. {
  1340.    int op, ev, err;
  1341.    /* Mesa's GLX isn't really an X extension but we try to act like one. */
  1342.    if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err))
  1343.       ev = err = 0;
  1344.    if (errorBase)
  1345.       *errorBase = err;
  1346.    if (eventBase)
  1347.       *eventBase = ev;
  1348.    return True; /* we're faking GLX so always return success */
  1349. }
  1350.  
  1351.  
  1352. PUBLIC void
  1353. glXDestroyContext( Display *dpy, GLXContext ctx )
  1354. {
  1355.    if (ctx) {
  1356.       GLXContext glxCtx = ctx;
  1357.       (void) dpy;
  1358.       MakeCurrent_PrevContext = 0;
  1359.       MakeCurrent_PrevDrawable = 0;
  1360.       MakeCurrent_PrevReadable = 0;
  1361.       MakeCurrent_PrevDrawBuffer = 0;
  1362.       MakeCurrent_PrevReadBuffer = 0;
  1363.       XMesaDestroyContext( glxCtx->xmesaContext );
  1364.       XMesaGarbageCollect();
  1365.       free(glxCtx);
  1366.    }
  1367. }
  1368.  
  1369.  
  1370. PUBLIC Bool
  1371. glXIsDirect( Display *dpy, GLXContext ctx )
  1372. {
  1373.    return ctx ? ctx->isDirect : False;
  1374. }
  1375.  
  1376.  
  1377.  
  1378. PUBLIC void
  1379. glXSwapBuffers( Display *dpy, GLXDrawable drawable )
  1380. {
  1381.    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
  1382.    static boolean firsttime = 1, no_rast = 0;
  1383.  
  1384.    if (firsttime) {
  1385.       no_rast = getenv("SP_NO_RAST") != NULL;
  1386.       firsttime = 0;
  1387.    }
  1388.  
  1389.    if (no_rast)
  1390.       return;
  1391.  
  1392.    if (buffer) {
  1393.       XMesaSwapBuffers(buffer);
  1394.    }
  1395.    else if (_mesa_getenv("MESA_DEBUG")) {
  1396.       _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n",
  1397.                     (int) drawable);
  1398.    }
  1399. }
  1400.  
  1401.  
  1402.  
  1403. /*** GLX_MESA_copy_sub_buffer ***/
  1404.  
  1405. PUBLIC void
  1406. glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
  1407.                      int x, int y, int width, int height)
  1408. {
  1409.    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
  1410.    if (buffer) {
  1411.       XMesaCopySubBuffer(buffer, x, y, width, height);
  1412.    }
  1413.    else if (_mesa_getenv("MESA_DEBUG")) {
  1414.       _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n");
  1415.    }
  1416. }
  1417.  
  1418.  
  1419. PUBLIC Bool
  1420. glXQueryVersion( Display *dpy, int *maj, int *min )
  1421. {
  1422.    (void) dpy;
  1423.    /* Return GLX version, not Mesa version */
  1424.    assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
  1425.    *maj = CLIENT_MAJOR_VERSION;
  1426.    *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
  1427.    return True;
  1428. }
  1429.  
  1430.  
  1431. /*
  1432.  * Query the GLX attributes of the given XVisualInfo.
  1433.  */
  1434. static int
  1435. get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
  1436. {
  1437.    ASSERT(xmvis);
  1438.    switch(attrib) {
  1439.       case GLX_USE_GL:
  1440.          if (fbconfig)
  1441.             return GLX_BAD_ATTRIBUTE;
  1442.          *value = (int) True;
  1443.          return 0;
  1444.       case GLX_BUFFER_SIZE:
  1445.          *value = xmvis->visinfo->depth;
  1446.          return 0;
  1447.       case GLX_LEVEL:
  1448.          *value = xmvis->mesa_visual.level;
  1449.          return 0;
  1450.       case GLX_RGBA:
  1451.          if (fbconfig)
  1452.             return GLX_BAD_ATTRIBUTE;
  1453.          if (xmvis->mesa_visual.rgbMode) {
  1454.             *value = True;
  1455.          }
  1456.          else {
  1457.             *value = False;
  1458.          }
  1459.          return 0;
  1460.       case GLX_DOUBLEBUFFER:
  1461.          *value = (int) xmvis->mesa_visual.doubleBufferMode;
  1462.          return 0;
  1463.       case GLX_STEREO:
  1464.          *value = (int) xmvis->mesa_visual.stereoMode;
  1465.          return 0;
  1466.       case GLX_AUX_BUFFERS:
  1467.          *value = xmvis->mesa_visual.numAuxBuffers;
  1468.          return 0;
  1469.       case GLX_RED_SIZE:
  1470.          *value = xmvis->mesa_visual.redBits;
  1471.          return 0;
  1472.       case GLX_GREEN_SIZE:
  1473.          *value = xmvis->mesa_visual.greenBits;
  1474.          return 0;
  1475.       case GLX_BLUE_SIZE:
  1476.          *value = xmvis->mesa_visual.blueBits;
  1477.          return 0;
  1478.       case GLX_ALPHA_SIZE:
  1479.          *value = xmvis->mesa_visual.alphaBits;
  1480.          return 0;
  1481.       case GLX_DEPTH_SIZE:
  1482.          *value = xmvis->mesa_visual.depthBits;
  1483.          return 0;
  1484.       case GLX_STENCIL_SIZE:
  1485.          *value = xmvis->mesa_visual.stencilBits;
  1486.          return 0;
  1487.       case GLX_ACCUM_RED_SIZE:
  1488.          *value = xmvis->mesa_visual.accumRedBits;
  1489.          return 0;
  1490.       case GLX_ACCUM_GREEN_SIZE:
  1491.          *value = xmvis->mesa_visual.accumGreenBits;
  1492.          return 0;
  1493.       case GLX_ACCUM_BLUE_SIZE:
  1494.          *value = xmvis->mesa_visual.accumBlueBits;
  1495.          return 0;
  1496.       case GLX_ACCUM_ALPHA_SIZE:
  1497.          *value = xmvis->mesa_visual.accumAlphaBits;
  1498.          return 0;
  1499.  
  1500.       /*
  1501.        * GLX_EXT_visual_info extension
  1502.        */
  1503.       case GLX_X_VISUAL_TYPE_EXT:
  1504.          switch (xmvis->visinfo->CLASS) {
  1505.             case StaticGray:   *value = GLX_STATIC_GRAY_EXT;   return 0;
  1506.             case GrayScale:    *value = GLX_GRAY_SCALE_EXT;    return 0;
  1507.             case StaticColor:  *value = GLX_STATIC_GRAY_EXT;   return 0;
  1508.             case PseudoColor:  *value = GLX_PSEUDO_COLOR_EXT;  return 0;
  1509.             case TrueColor:    *value = GLX_TRUE_COLOR_EXT;    return 0;
  1510.             case DirectColor:  *value = GLX_DIRECT_COLOR_EXT;  return 0;
  1511.          }
  1512.          return 0;
  1513.       case GLX_TRANSPARENT_TYPE_EXT:
  1514.          /* normal planes */
  1515.          *value = GLX_NONE_EXT;
  1516.          return 0;
  1517.       case GLX_TRANSPARENT_INDEX_VALUE_EXT:
  1518.          /* undefined */
  1519.          return 0;
  1520.       case GLX_TRANSPARENT_RED_VALUE_EXT:
  1521.          /* undefined */
  1522.          return 0;
  1523.       case GLX_TRANSPARENT_GREEN_VALUE_EXT:
  1524.          /* undefined */
  1525.          return 0;
  1526.       case GLX_TRANSPARENT_BLUE_VALUE_EXT:
  1527.          /* undefined */
  1528.          return 0;
  1529.       case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
  1530.          /* undefined */
  1531.          return 0;
  1532.  
  1533.       /*
  1534.        * GLX_EXT_visual_info extension
  1535.        */
  1536.       case GLX_VISUAL_CAVEAT_EXT:
  1537.          /* test for zero, just in case */
  1538.          if (xmvis->mesa_visual.visualRating > 0)
  1539.             *value = xmvis->mesa_visual.visualRating;
  1540.          else
  1541.             *value = GLX_NONE_EXT;
  1542.          return 0;
  1543.  
  1544.       /*
  1545.        * GLX_ARB_multisample
  1546.        */
  1547.       case GLX_SAMPLE_BUFFERS_ARB:
  1548.          *value = 0;
  1549.          return 0;
  1550.       case GLX_SAMPLES_ARB:
  1551.          *value = 0;
  1552.          return 0;
  1553.  
  1554.       /*
  1555.        * For FBConfigs:
  1556.        */
  1557.       case GLX_SCREEN_EXT:
  1558.          if (!fbconfig)
  1559.             return GLX_BAD_ATTRIBUTE;
  1560.          *value = xmvis->visinfo->screen;
  1561.          break;
  1562.       case GLX_DRAWABLE_TYPE: /*SGIX too */
  1563.          if (!fbconfig)
  1564.             return GLX_BAD_ATTRIBUTE;
  1565.          *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
  1566.          break;
  1567.       case GLX_RENDER_TYPE_SGIX:
  1568.          if (!fbconfig)
  1569.             return GLX_BAD_ATTRIBUTE;
  1570.          if (xmvis->mesa_visual.rgbMode)
  1571.             *value = GLX_RGBA_BIT;
  1572.          else
  1573.             *value = GLX_COLOR_INDEX_BIT;
  1574.          break;
  1575.       case GLX_X_RENDERABLE_SGIX:
  1576.          if (!fbconfig)
  1577.             return GLX_BAD_ATTRIBUTE;
  1578.          *value = True; /* XXX really? */
  1579.          break;
  1580.       case GLX_FBCONFIG_ID_SGIX:
  1581.          if (!fbconfig)
  1582.             return GLX_BAD_ATTRIBUTE;
  1583.          *value = xmvis->visinfo->visualid;
  1584.          break;
  1585.       case GLX_MAX_PBUFFER_WIDTH:
  1586.          if (!fbconfig)
  1587.             return GLX_BAD_ATTRIBUTE;
  1588.          /* XXX or MAX_WIDTH? */
  1589.          *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen);
  1590.          break;
  1591.       case GLX_MAX_PBUFFER_HEIGHT:
  1592.          if (!fbconfig)
  1593.             return GLX_BAD_ATTRIBUTE;
  1594.          *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen);
  1595.          break;
  1596.       case GLX_MAX_PBUFFER_PIXELS:
  1597.          if (!fbconfig)
  1598.             return GLX_BAD_ATTRIBUTE;
  1599.          *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) *
  1600.                   DisplayHeight(xmvis->display, xmvis->visinfo->screen);
  1601.          break;
  1602.       case GLX_VISUAL_ID:
  1603.          if (!fbconfig)
  1604.             return GLX_BAD_ATTRIBUTE;
  1605.          *value = xmvis->visinfo->visualid;
  1606.          break;
  1607.  
  1608. #ifdef GLX_EXT_texture_from_pixmap
  1609.       case GLX_BIND_TO_TEXTURE_RGB_EXT:
  1610.          *value = True; /*XXX*/
  1611.          break;
  1612.       case GLX_BIND_TO_TEXTURE_RGBA_EXT:
  1613.          /* XXX review */
  1614.          *value = xmvis->mesa_visual.alphaBits > 0 ? True : False;
  1615.          break;
  1616.       case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
  1617.          *value = True; /*XXX*/
  1618.          break;
  1619.       case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
  1620.          *value = (GLX_TEXTURE_1D_BIT_EXT |
  1621.                    GLX_TEXTURE_2D_BIT_EXT |
  1622.                    GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/
  1623.          break;
  1624.       case GLX_Y_INVERTED_EXT:
  1625.          *value = True; /*XXX*/
  1626.          break;
  1627. #endif
  1628.  
  1629.       default:
  1630.          return GLX_BAD_ATTRIBUTE;
  1631.    }
  1632.    return Success;
  1633. }
  1634.  
  1635.  
  1636. PUBLIC int
  1637. glXGetConfig( Display *dpy, XVisualInfo *visinfo,
  1638.                    int attrib, int *value )
  1639. {
  1640.    XMesaVisual xmvis;
  1641.    int k;
  1642.    if (!dpy || !visinfo)
  1643.       return GLX_BAD_ATTRIBUTE;
  1644.  
  1645.    xmvis = find_glx_visual( dpy, visinfo );
  1646.    if (!xmvis) {
  1647.       /* this visual wasn't obtained with glXChooseVisual */
  1648.       xmvis = create_glx_visual( dpy, visinfo );
  1649.       if (!xmvis) {
  1650.          /* this visual can't be used for GL rendering */
  1651.          if (attrib==GLX_USE_GL) {
  1652.             *value = (int) False;
  1653.             return 0;
  1654.          }
  1655.          else {
  1656.             return GLX_BAD_VISUAL;
  1657.          }
  1658.       }
  1659.    }
  1660.  
  1661.    k = get_config(xmvis, attrib, value, GL_FALSE);
  1662.    return k;
  1663. }
  1664.  
  1665.  
  1666. PUBLIC void
  1667. glXWaitGL( void )
  1668. {
  1669.    XMesaContext xmesa = XMesaGetCurrentContext();
  1670.    XMesaFlush( xmesa );
  1671. }
  1672.  
  1673.  
  1674.  
  1675. PUBLIC void
  1676. glXWaitX( void )
  1677. {
  1678.    XMesaContext xmesa = XMesaGetCurrentContext();
  1679.    XMesaFlush( xmesa );
  1680. }
  1681.  
  1682.  
  1683. static const char *
  1684. get_extensions( void )
  1685. {
  1686.    return EXTENSIONS;
  1687. }
  1688.  
  1689.  
  1690.  
  1691. /* GLX 1.1 and later */
  1692. PUBLIC const char *
  1693. glXQueryExtensionsString( Display *dpy, int screen )
  1694. {
  1695.    (void) dpy;
  1696.    (void) screen;
  1697.    return get_extensions();
  1698. }
  1699.  
  1700.  
  1701.  
  1702. /* GLX 1.1 and later */
  1703. PUBLIC const char *
  1704. glXQueryServerString( Display *dpy, int screen, int name )
  1705. {
  1706.    static char version[1000];
  1707.    sprintf(version, "%d.%d %s",
  1708.            SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, xmesa_get_name());
  1709.  
  1710.    (void) dpy;
  1711.    (void) screen;
  1712.  
  1713.    switch (name) {
  1714.       case GLX_EXTENSIONS:
  1715.          return get_extensions();
  1716.       case GLX_VENDOR:
  1717.          return VENDOR;
  1718.       case GLX_VERSION:
  1719.          return version;
  1720.       default:
  1721.          return NULL;
  1722.    }
  1723. }
  1724.  
  1725.  
  1726.  
  1727. /* GLX 1.1 and later */
  1728. PUBLIC const char *
  1729. glXGetClientString( Display *dpy, int name )
  1730. {
  1731.    static char version[1000];
  1732.    sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
  1733.            CLIENT_MINOR_VERSION, xmesa_get_name());
  1734.  
  1735.    (void) dpy;
  1736.  
  1737.    switch (name) {
  1738.       case GLX_EXTENSIONS:
  1739.          return get_extensions();
  1740.       case GLX_VENDOR:
  1741.          return VENDOR;
  1742.       case GLX_VERSION:
  1743.          return version;
  1744.       default:
  1745.          return NULL;
  1746.    }
  1747. }
  1748.  
  1749.  
  1750.  
  1751. /*
  1752.  * GLX 1.3 and later
  1753.  */
  1754.  
  1755.  
  1756. PUBLIC int
  1757. glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config,
  1758.                      int attribute, int *value)
  1759. {
  1760.    XMesaVisual v = (XMesaVisual) config;
  1761.    (void) dpy;
  1762.    (void) config;
  1763.  
  1764.    if (!dpy || !config || !value)
  1765.       return -1;
  1766.  
  1767.    return get_config(v, attribute, value, GL_TRUE);
  1768. }
  1769.  
  1770.  
  1771. PUBLIC GLXFBConfig *
  1772. glXGetFBConfigs( Display *dpy, int screen, int *nelements )
  1773. {
  1774.    XVisualInfo *visuals, visTemplate;
  1775.    const long visMask = VisualScreenMask;
  1776.    int i;
  1777.  
  1778.    /* Get list of all X visuals */
  1779.    visTemplate.screen = screen;
  1780.    visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
  1781.    if (*nelements > 0) {
  1782.       XMesaVisual *results;
  1783.       results = (XMesaVisual *) malloc(*nelements * sizeof(XMesaVisual));
  1784.       if (!results) {
  1785.          *nelements = 0;
  1786.          return NULL;
  1787.       }
  1788.       for (i = 0; i < *nelements; i++) {
  1789.          results[i] = create_glx_visual(dpy, visuals + i);
  1790.          if (!results[i]) {
  1791.             *nelements = i;
  1792.             break;
  1793.          }
  1794.       }
  1795.       return (GLXFBConfig *) results;
  1796.    }
  1797.    return NULL;
  1798. }
  1799.  
  1800.  
  1801. PUBLIC GLXFBConfig *
  1802. glXChooseFBConfig(Display *dpy, int screen,
  1803.                   const int *attribList, int *nitems)
  1804. {
  1805.    XMesaVisual xmvis;
  1806.  
  1807.    /* register ourselves as an extension on this display */
  1808.    register_with_display(dpy);
  1809.  
  1810.    if (!attribList || !attribList[0]) {
  1811.       /* return list of all configs (per GLX_SGIX_fbconfig spec) */
  1812.       return glXGetFBConfigs(dpy, screen, nitems);
  1813.    }
  1814.  
  1815.    xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
  1816.    if (xmvis) {
  1817.       GLXFBConfig *config = (GLXFBConfig *) malloc(sizeof(XMesaVisual));
  1818.       if (!config) {
  1819.          *nitems = 0;
  1820.          return NULL;
  1821.       }
  1822.       *nitems = 1;
  1823.       config[0] = (GLXFBConfig) xmvis;
  1824.       return (GLXFBConfig *) config;
  1825.    }
  1826.    else {
  1827.       *nitems = 0;
  1828.       return NULL;
  1829.    }
  1830. }
  1831.  
  1832.  
  1833. PUBLIC XVisualInfo *
  1834. glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
  1835. {
  1836.    if (dpy && config) {
  1837.       XMesaVisual xmvis = (XMesaVisual) config;
  1838. #if 0      
  1839.       return xmvis->vishandle;
  1840. #else
  1841.       /* create a new vishandle - the cached one may be stale */
  1842.       xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo));
  1843.       if (xmvis->vishandle) {
  1844.          memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
  1845.       }
  1846.       return xmvis->vishandle;
  1847. #endif
  1848.    }
  1849.    else {
  1850.       return NULL;
  1851.    }
  1852. }
  1853.  
  1854.  
  1855. PUBLIC GLXWindow
  1856. glXCreateWindow(Display *dpy, GLXFBConfig config, Window win,
  1857.                 const int *attribList)
  1858. {
  1859.    XMesaVisual xmvis = (XMesaVisual) config;
  1860.    XMesaBuffer xmbuf;
  1861.    if (!xmvis)
  1862.       return 0;
  1863.  
  1864.    xmbuf = XMesaCreateWindowBuffer(xmvis, win);
  1865.    if (!xmbuf)
  1866.       return 0;
  1867.  
  1868.    (void) dpy;
  1869.    (void) attribList;  /* Ignored in GLX 1.3 */
  1870.  
  1871.    return win;  /* A hack for now */
  1872. }
  1873.  
  1874.  
  1875. PUBLIC void
  1876. glXDestroyWindow( Display *dpy, GLXWindow window )
  1877. {
  1878.    XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window);
  1879.    if (b)
  1880.       XMesaDestroyBuffer(b);
  1881.    /* don't destroy X window */
  1882. }
  1883.  
  1884.  
  1885. /* XXX untested */
  1886. PUBLIC GLXPixmap
  1887. glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap,
  1888.                 const int *attribList)
  1889. {
  1890.    XMesaVisual v = (XMesaVisual) config;
  1891.    XMesaBuffer b;
  1892.    const int *attr;
  1893.    int target = 0, format = 0, mipmap = 0;
  1894.    int value;
  1895.  
  1896.    if (!dpy || !config || !pixmap)
  1897.       return 0;
  1898.  
  1899.    for (attr = attribList; attr && *attr; attr++) {
  1900.       switch (*attr) {
  1901.       case GLX_TEXTURE_FORMAT_EXT:
  1902.          attr++;
  1903.          switch (*attr) {
  1904.          case GLX_TEXTURE_FORMAT_NONE_EXT:
  1905.          case GLX_TEXTURE_FORMAT_RGB_EXT:
  1906.          case GLX_TEXTURE_FORMAT_RGBA_EXT:
  1907.             format = *attr;
  1908.             break;
  1909.          default:
  1910.             /* error */
  1911.             return 0;
  1912.          }
  1913.          break;
  1914.       case GLX_TEXTURE_TARGET_EXT:
  1915.          attr++;
  1916.          switch (*attr) {
  1917.          case GLX_TEXTURE_1D_EXT:
  1918.          case GLX_TEXTURE_2D_EXT:
  1919.          case GLX_TEXTURE_RECTANGLE_EXT:
  1920.             target = *attr;
  1921.             break;
  1922.          default:
  1923.             /* error */
  1924.             return 0;
  1925.          }
  1926.          break;
  1927.       case GLX_MIPMAP_TEXTURE_EXT:
  1928.          attr++;
  1929.          if (*attr)
  1930.             mipmap = 1;
  1931.          break;
  1932.       default:
  1933.          /* error */
  1934.          return 0;
  1935.       }
  1936.    }
  1937.  
  1938.    if (format == GLX_TEXTURE_FORMAT_RGB_EXT) {
  1939.       if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT,
  1940.                      &value, GL_TRUE) != Success
  1941.           || !value) {
  1942.          return 0; /* error! */
  1943.       }
  1944.    }
  1945.    else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) {
  1946.       if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT,
  1947.                      &value, GL_TRUE) != Success
  1948.           || !value) {
  1949.          return 0; /* error! */
  1950.       }
  1951.    }
  1952.    if (mipmap) {
  1953.       if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
  1954.                      &value, GL_TRUE) != Success
  1955.           || !value) {
  1956.          return 0; /* error! */
  1957.       }
  1958.    }
  1959.    if (target == GLX_TEXTURE_1D_EXT) {
  1960.       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
  1961.                      &value, GL_TRUE) != Success
  1962.           || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) {
  1963.          return 0; /* error! */
  1964.       }
  1965.    }
  1966.    else if (target == GLX_TEXTURE_2D_EXT) {
  1967.       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
  1968.                      &value, GL_TRUE) != Success
  1969.           || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) {
  1970.          return 0; /* error! */
  1971.       }
  1972.    }
  1973.    if (target == GLX_TEXTURE_RECTANGLE_EXT) {
  1974.       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
  1975.                      &value, GL_TRUE) != Success
  1976.           || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) {
  1977.          return 0; /* error! */
  1978.       }
  1979.    }
  1980.  
  1981.    if (format || target || mipmap) {
  1982.       /* texture from pixmap */
  1983.       b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap);
  1984.    }
  1985.    else {
  1986.       b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
  1987.    }
  1988.    if (!b) {
  1989.       return 0;
  1990.    }
  1991.  
  1992.    return pixmap;
  1993. }
  1994.  
  1995.  
  1996. PUBLIC void
  1997. glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
  1998. {
  1999.    XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap);
  2000.    if (b)
  2001.       XMesaDestroyBuffer(b);
  2002.    /* don't destroy X pixmap */
  2003. }
  2004.  
  2005.  
  2006. PUBLIC GLXPbuffer
  2007. glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
  2008. {
  2009.    XMesaVisual xmvis = (XMesaVisual) config;
  2010.    XMesaBuffer xmbuf;
  2011.    const int *attrib;
  2012.    int width = 0, height = 0;
  2013.    GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
  2014.  
  2015.    (void) dpy;
  2016.  
  2017.    for (attrib = attribList; *attrib; attrib++) {
  2018.       switch (*attrib) {
  2019.          case GLX_PBUFFER_WIDTH:
  2020.             attrib++;
  2021.             width = *attrib;
  2022.             break;
  2023.          case GLX_PBUFFER_HEIGHT:
  2024.             attrib++;
  2025.             height = *attrib;
  2026.             break;
  2027.          case GLX_PRESERVED_CONTENTS:
  2028.             attrib++;
  2029.             preserveContents = *attrib;
  2030.             break;
  2031.          case GLX_LARGEST_PBUFFER:
  2032.             attrib++;
  2033.             useLargest = *attrib;
  2034.             break;
  2035.          default:
  2036.             return 0;
  2037.       }
  2038.    }
  2039.  
  2040.    if (width == 0 || height == 0)
  2041.       return 0;
  2042.  
  2043.    if (width > PBUFFER_MAX_SIZE || height > PBUFFER_MAX_SIZE) {
  2044.       /* If allocation would have failed and GLX_LARGEST_PBUFFER is set,
  2045.        * allocate the largest possible buffer.
  2046.        */
  2047.       if (useLargest) {
  2048.          width = PBUFFER_MAX_SIZE;
  2049.          height = PBUFFER_MAX_SIZE;
  2050.       }
  2051.    }
  2052.  
  2053.    xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
  2054.    /* A GLXPbuffer handle must be an X Drawable because that's what
  2055.     * glXMakeCurrent takes.
  2056.     */
  2057.    if (xmbuf) {
  2058.       xmbuf->largestPbuffer = useLargest;
  2059.       xmbuf->preservedContents = preserveContents;
  2060.       return (GLXPbuffer) xmbuf->ws.drawable;
  2061.    }
  2062.    else {
  2063.       return 0;
  2064.    }
  2065. }
  2066.  
  2067.  
  2068. PUBLIC void
  2069. glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
  2070. {
  2071.    XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
  2072.    if (b) {
  2073.       XMesaDestroyBuffer(b);
  2074.    }
  2075. }
  2076.  
  2077.  
  2078. PUBLIC void
  2079. glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
  2080.                  unsigned int *value)
  2081. {
  2082.    GLuint width, height;
  2083.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
  2084.    if (!xmbuf)
  2085.       return;
  2086.  
  2087.    /* make sure buffer's dimensions are up to date */
  2088.    xmesa_get_window_size(dpy, xmbuf, &width, &height);
  2089.  
  2090.    switch (attribute) {
  2091.       case GLX_WIDTH:
  2092.          *value = width;
  2093.          break;
  2094.       case GLX_HEIGHT:
  2095.          *value = height;
  2096.          break;
  2097.       case GLX_PRESERVED_CONTENTS:
  2098.          *value = xmbuf->preservedContents;
  2099.          break;
  2100.       case GLX_LARGEST_PBUFFER:
  2101.          *value = xmbuf->largestPbuffer;
  2102.          break;
  2103.       case GLX_FBCONFIG_ID:
  2104.          *value = xmbuf->xm_visual->visinfo->visualid;
  2105.          return;
  2106. #ifdef GLX_EXT_texture_from_pixmap
  2107.       case GLX_TEXTURE_FORMAT_EXT:
  2108.          *value = xmbuf->TextureFormat;
  2109.          break;
  2110.       case GLX_TEXTURE_TARGET_EXT:
  2111.          *value = xmbuf->TextureTarget;
  2112.          break;
  2113.       case GLX_MIPMAP_TEXTURE_EXT:
  2114.          *value = xmbuf->TextureMipmap;
  2115.          break;
  2116. #endif
  2117.  
  2118.       default:
  2119.          return; /* raise BadValue error */
  2120.    }
  2121. }
  2122.  
  2123.  
  2124. PUBLIC GLXContext
  2125. glXCreateNewContext( Display *dpy, GLXFBConfig config,
  2126.                      int renderType, GLXContext shareCtx, Bool direct )
  2127. {
  2128.    XMesaVisual xmvis = (XMesaVisual) config;
  2129.  
  2130.    if (!dpy || !config ||
  2131.        (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
  2132.       return 0;
  2133.  
  2134.    return create_context(dpy, xmvis,
  2135.                          shareCtx ? shareCtx->xmesaContext : NULL,
  2136.                          direct,
  2137.                          1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
  2138. }
  2139.  
  2140.  
  2141. PUBLIC int
  2142. glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
  2143. {
  2144.    GLXContext glxCtx = ctx;
  2145.    XMesaContext xmctx = glxCtx->xmesaContext;
  2146.  
  2147.    (void) dpy;
  2148.    (void) ctx;
  2149.  
  2150.    switch (attribute) {
  2151.    case GLX_FBCONFIG_ID:
  2152.       *value = xmctx->xm_visual->visinfo->visualid;
  2153.       break;
  2154.    case GLX_RENDER_TYPE:
  2155.       if (xmctx->xm_visual->mesa_visual.rgbMode)
  2156.          *value = GLX_RGBA_TYPE;
  2157.       else
  2158.          *value = GLX_COLOR_INDEX_TYPE;
  2159.       break;
  2160.    case GLX_SCREEN:
  2161.       *value = 0;
  2162.       return Success;
  2163.    default:
  2164.       return GLX_BAD_ATTRIBUTE;
  2165.    }
  2166.    return 0;
  2167. }
  2168.  
  2169.  
  2170. PUBLIC void
  2171. glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
  2172. {
  2173.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
  2174.    if (xmbuf)
  2175.       xmbuf->selectedEvents = mask;
  2176. }
  2177.  
  2178.  
  2179. PUBLIC void
  2180. glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
  2181. {
  2182.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
  2183.    if (xmbuf)
  2184.       *mask = xmbuf->selectedEvents;
  2185.    else
  2186.       *mask = 0;
  2187. }
  2188.  
  2189.  
  2190.  
  2191. /*** GLX_SGI_swap_control ***/
  2192.  
  2193. PUBLIC int
  2194. glXSwapIntervalSGI(int interval)
  2195. {
  2196.    (void) interval;
  2197.    return 0;
  2198. }
  2199.  
  2200.  
  2201.  
  2202. /*** GLX_SGI_video_sync ***/
  2203.  
  2204. static unsigned int FrameCounter = 0;
  2205.  
  2206. PUBLIC int
  2207. glXGetVideoSyncSGI(unsigned int *count)
  2208. {
  2209.    /* this is a bogus implementation */
  2210.    *count = FrameCounter++;
  2211.    return 0;
  2212. }
  2213.  
  2214. PUBLIC int
  2215. glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
  2216. {
  2217.    if (divisor <= 0 || remainder < 0)
  2218.       return GLX_BAD_VALUE;
  2219.    /* this is a bogus implementation */
  2220.    FrameCounter++;
  2221.    while (FrameCounter % divisor != remainder)
  2222.       FrameCounter++;
  2223.    *count = FrameCounter;
  2224.    return 0;
  2225. }
  2226.  
  2227.  
  2228.  
  2229. /*** GLX_SGI_make_current_read ***/
  2230.  
  2231. PUBLIC Bool
  2232. glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read,
  2233.                       GLXContext ctx)
  2234. {
  2235.    return glXMakeContextCurrent( dpy, draw, read, ctx );
  2236. }
  2237.  
  2238. /* not used
  2239. static GLXDrawable
  2240. glXGetCurrentReadDrawableSGI(void)
  2241. {
  2242.    return 0;
  2243. }
  2244. */
  2245.  
  2246.  
  2247. /*** GLX_SGIX_video_source ***/
  2248. #if defined(_VL_H)
  2249.  
  2250. PUBLIC GLXVideoSourceSGIX
  2251. glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server,
  2252.                             VLPath path, int nodeClass, VLNode drainNode)
  2253. {
  2254.    (void) dpy;
  2255.    (void) screen;
  2256.    (void) server;
  2257.    (void) path;
  2258.    (void) nodeClass;
  2259.    (void) drainNode;
  2260.    return 0;
  2261. }
  2262.  
  2263. PUBLIC void
  2264. glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
  2265. {
  2266.    (void) dpy;
  2267.    (void) src;
  2268. }
  2269.  
  2270. #endif
  2271.  
  2272.  
  2273. /*** GLX_EXT_import_context ***/
  2274.  
  2275. PUBLIC void
  2276. glXFreeContextEXT(Display *dpy, GLXContext context)
  2277. {
  2278.    (void) dpy;
  2279.    (void) context;
  2280. }
  2281.  
  2282. PUBLIC GLXContextID
  2283. glXGetContextIDEXT(const GLXContext context)
  2284. {
  2285.    (void) context;
  2286.    return 0;
  2287. }
  2288.  
  2289. PUBLIC GLXContext
  2290. glXImportContextEXT(Display *dpy, GLXContextID contextID)
  2291. {
  2292.    (void) dpy;
  2293.    (void) contextID;
  2294.    return 0;
  2295. }
  2296.  
  2297. PUBLIC int
  2298. glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,
  2299.                        int *value)
  2300. {
  2301.    (void) dpy;
  2302.    (void) context;
  2303.    (void) attribute;
  2304.    (void) value;
  2305.    return 0;
  2306. }
  2307.  
  2308.  
  2309.  
  2310. /*** GLX_SGIX_fbconfig ***/
  2311.  
  2312. PUBLIC int
  2313. glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config,
  2314.                          int attribute, int *value)
  2315. {
  2316.    return glXGetFBConfigAttrib(dpy, config, attribute, value);
  2317. }
  2318.  
  2319. PUBLIC GLXFBConfigSGIX *
  2320. glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list,
  2321.                       int *nelements)
  2322. {
  2323.    return (GLXFBConfig *) glXChooseFBConfig(dpy, screen,
  2324.                                             attrib_list, nelements);
  2325. }
  2326.  
  2327.  
  2328. PUBLIC GLXPixmap
  2329. glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
  2330.                                  Pixmap pixmap)
  2331. {
  2332.    XMesaVisual xmvis = (XMesaVisual) config;
  2333.    XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
  2334.    return xmbuf->ws.drawable; /* need to return an X ID */
  2335. }
  2336.  
  2337.  
  2338. PUBLIC GLXContext
  2339. glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
  2340.                                int renderType, GLXContext shareCtx,
  2341.                                Bool direct)
  2342. {
  2343.    XMesaVisual xmvis = (XMesaVisual) config;
  2344.  
  2345.    if (!dpy || !config ||
  2346.        (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
  2347.       return 0;
  2348.  
  2349.    return create_context(dpy, xmvis,
  2350.                          shareCtx ? shareCtx->xmesaContext : NULL,
  2351.                          direct,
  2352.                          1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
  2353. }
  2354.  
  2355.  
  2356. PUBLIC XVisualInfo *
  2357. glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
  2358. {
  2359.    return glXGetVisualFromFBConfig(dpy, config);
  2360. }
  2361.  
  2362.  
  2363. PUBLIC GLXFBConfigSGIX
  2364. glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
  2365. {
  2366.    XMesaVisual xmvis = find_glx_visual(dpy, vis);
  2367.    if (!xmvis) {
  2368.       /* This visual wasn't found with glXChooseVisual() */
  2369.       xmvis = create_glx_visual(dpy, vis);
  2370.    }
  2371.  
  2372.    return (GLXFBConfigSGIX) xmvis;
  2373. }
  2374.  
  2375.  
  2376.  
  2377. /*** GLX_SGIX_pbuffer ***/
  2378.  
  2379. PUBLIC GLXPbufferSGIX
  2380. glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
  2381.                         unsigned int width, unsigned int height,
  2382.                         int *attribList)
  2383. {
  2384.    XMesaVisual xmvis = (XMesaVisual) config;
  2385.    XMesaBuffer xmbuf;
  2386.    const int *attrib;
  2387.    GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
  2388.  
  2389.    (void) dpy;
  2390.  
  2391.    for (attrib = attribList; attrib && *attrib; attrib++) {
  2392.       switch (*attrib) {
  2393.          case GLX_PRESERVED_CONTENTS_SGIX:
  2394.             attrib++;
  2395.             preserveContents = *attrib; /* ignored */
  2396.             break;
  2397.          case GLX_LARGEST_PBUFFER_SGIX:
  2398.             attrib++;
  2399.             useLargest = *attrib; /* ignored */
  2400.             break;
  2401.          default:
  2402.             return 0;
  2403.       }
  2404.    }
  2405.  
  2406.    /* not used at this time */
  2407.    (void) useLargest;
  2408.    (void) preserveContents;
  2409.  
  2410.    xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
  2411.    /* A GLXPbuffer handle must be an X Drawable because that's what
  2412.     * glXMakeCurrent takes.
  2413.     */
  2414.    return (GLXPbuffer) xmbuf->ws.drawable;
  2415. }
  2416.  
  2417.  
  2418. PUBLIC void
  2419. glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
  2420. {
  2421.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
  2422.    if (xmbuf) {
  2423.       XMesaDestroyBuffer(xmbuf);
  2424.    }
  2425. }
  2426.  
  2427.  
  2428. PUBLIC int
  2429. glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute,
  2430.                        unsigned int *value)
  2431. {
  2432.    const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
  2433.  
  2434.    if (!xmbuf) {
  2435.       /* Generate GLXBadPbufferSGIX for bad pbuffer */
  2436.       return 0;
  2437.    }
  2438.  
  2439.    switch (attribute) {
  2440.       case GLX_PRESERVED_CONTENTS_SGIX:
  2441.          *value = True;
  2442.          break;
  2443.       case GLX_LARGEST_PBUFFER_SGIX:
  2444.          *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf);
  2445.          break;
  2446.       case GLX_WIDTH_SGIX:
  2447.          *value = xmesa_buffer_width(xmbuf);
  2448.          break;
  2449.       case GLX_HEIGHT_SGIX:
  2450.          *value = xmesa_buffer_height(xmbuf);
  2451.          break;
  2452.       case GLX_EVENT_MASK_SGIX:
  2453.          *value = 0;  /* XXX might be wrong */
  2454.          break;
  2455.       default:
  2456.          *value = 0;
  2457.    }
  2458.    return 0;
  2459. }
  2460.  
  2461.  
  2462. PUBLIC void
  2463. glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
  2464. {
  2465.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
  2466.    if (xmbuf) {
  2467.       /* Note: we'll never generate clobber events */
  2468.       xmbuf->selectedEvents = mask;
  2469.    }
  2470. }
  2471.  
  2472.  
  2473. PUBLIC void
  2474. glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable,
  2475.                         unsigned long *mask)
  2476. {
  2477.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
  2478.    if (xmbuf) {
  2479.       *mask = xmbuf->selectedEvents;
  2480.    }
  2481.    else {
  2482.       *mask = 0;
  2483.    }
  2484. }
  2485.  
  2486.  
  2487.  
  2488. /*** GLX_SGI_cushion ***/
  2489.  
  2490. PUBLIC void
  2491. glXCushionSGI(Display *dpy, Window win, float cushion)
  2492. {
  2493.    (void) dpy;
  2494.    (void) win;
  2495.    (void) cushion;
  2496. }
  2497.  
  2498.  
  2499.  
  2500. /*** GLX_SGIX_video_resize ***/
  2501.  
  2502. PUBLIC int
  2503. glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel,
  2504.                            Window window)
  2505. {
  2506.    (void) dpy;
  2507.    (void) screen;
  2508.    (void) channel;
  2509.    (void) window;
  2510.    return 0;
  2511. }
  2512.  
  2513. PUBLIC int
  2514. glXChannelRectSGIX(Display *dpy, int screen, int channel,
  2515.                    int x, int y, int w, int h)
  2516. {
  2517.    (void) dpy;
  2518.    (void) screen;
  2519.    (void) channel;
  2520.    (void) x;
  2521.    (void) y;
  2522.    (void) w;
  2523.    (void) h;
  2524.    return 0;
  2525. }
  2526.  
  2527. PUBLIC int
  2528. glXQueryChannelRectSGIX(Display *dpy, int screen, int channel,
  2529.                         int *x, int *y, int *w, int *h)
  2530. {
  2531.    (void) dpy;
  2532.    (void) screen;
  2533.    (void) channel;
  2534.    (void) x;
  2535.    (void) y;
  2536.    (void) w;
  2537.    (void) h;
  2538.    return 0;
  2539. }
  2540.  
  2541. PUBLIC int
  2542. glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel,
  2543.                           int *dx, int *dy, int *dw, int *dh)
  2544. {
  2545.    (void) dpy;
  2546.    (void) screen;
  2547.    (void) channel;
  2548.    (void) dx;
  2549.    (void) dy;
  2550.    (void) dw;
  2551.    (void) dh;
  2552.    return 0;
  2553. }
  2554.  
  2555. PUBLIC int
  2556. glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
  2557. {
  2558.    (void) dpy;
  2559.    (void) screen;
  2560.    (void) channel;
  2561.    (void) synctype;
  2562.    return 0;
  2563. }
  2564.  
  2565.  
  2566.  
  2567. /*** GLX_SGIX_dmbuffer **/
  2568.  
  2569. #if defined(_DM_BUFFER_H_)
  2570. PUBLIC Bool
  2571. glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer,
  2572.                           DMparams *params, DMbuffer dmbuffer)
  2573. {
  2574.    (void) dpy;
  2575.    (void) pbuffer;
  2576.    (void) params;
  2577.    (void) dmbuffer;
  2578.    return False;
  2579. }
  2580. #endif
  2581.  
  2582.  
  2583. /*** GLX_SGIX_swap_group ***/
  2584.  
  2585. PUBLIC void
  2586. glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
  2587. {
  2588.    (void) dpy;
  2589.    (void) drawable;
  2590.    (void) member;
  2591. }
  2592.  
  2593.  
  2594.  
  2595. /*** GLX_SGIX_swap_barrier ***/
  2596.  
  2597. PUBLIC void
  2598. glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
  2599. {
  2600.    (void) dpy;
  2601.    (void) drawable;
  2602.    (void) barrier;
  2603. }
  2604.  
  2605. PUBLIC Bool
  2606. glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
  2607. {
  2608.    (void) dpy;
  2609.    (void) screen;
  2610.    (void) max;
  2611.    return False;
  2612. }
  2613.  
  2614.  
  2615.  
  2616. /*** GLX_SUN_get_transparent_index ***/
  2617.  
  2618. PUBLIC Status
  2619. glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay,
  2620.                           long *pTransparent)
  2621. {
  2622.    (void) dpy;
  2623.    (void) overlay;
  2624.    (void) underlay;
  2625.    (void) pTransparent;
  2626.    return 0;
  2627. }
  2628.  
  2629.  
  2630.  
  2631. /*** GLX_MESA_release_buffers ***/
  2632.  
  2633. /*
  2634.  * Release the depth, stencil, accum buffers attached to a GLXDrawable
  2635.  * (a window or pixmap) prior to destroying the GLXDrawable.
  2636.  */
  2637. PUBLIC Bool
  2638. glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
  2639. {
  2640.    XMesaBuffer b = XMesaFindBuffer(dpy, d);
  2641.    if (b) {
  2642.       XMesaDestroyBuffer(b);
  2643.       return True;
  2644.    }
  2645.    return False;
  2646. }
  2647.  
  2648. /*** GLX_EXT_texture_from_pixmap ***/
  2649.  
  2650. PUBLIC void
  2651. glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
  2652.                         const int *attrib_list)
  2653. {
  2654.    XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
  2655.    if (b)
  2656.       XMesaBindTexImage(dpy, b, buffer, attrib_list);
  2657. }
  2658.  
  2659. PUBLIC void
  2660. glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
  2661. {
  2662.    XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
  2663.    if (b)
  2664.       XMesaReleaseTexImage(dpy, b, buffer);
  2665. }
  2666.  
  2667.  
  2668.  
  2669. /*** GLX_ARB_create_context ***/
  2670.  
  2671. GLXContext
  2672. glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
  2673.                            GLXContext shareCtx, Bool direct,
  2674.                            const int *attrib_list)
  2675. {
  2676.    XMesaVisual xmvis = (XMesaVisual) config;
  2677.    int majorVersion = 1, minorVersion = 0;
  2678.    int contextFlags = 0x0;
  2679.    int profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
  2680.    int renderType = GLX_RGBA_TYPE;
  2681.    unsigned i;
  2682.    Bool done = False;
  2683.    const int contextFlagsAll = (GLX_CONTEXT_DEBUG_BIT_ARB |
  2684.                                 GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
  2685.  
  2686.    /* parse attrib_list */
  2687.    for (i = 0; !done && attrib_list && attrib_list[i]; i++) {
  2688.       switch (attrib_list[i]) {
  2689.       case GLX_CONTEXT_MAJOR_VERSION_ARB:
  2690.          majorVersion = attrib_list[++i];
  2691.          break;
  2692.       case GLX_CONTEXT_MINOR_VERSION_ARB:
  2693.          minorVersion = attrib_list[++i];
  2694.          break;
  2695.       case GLX_CONTEXT_FLAGS_ARB:
  2696.          contextFlags = attrib_list[++i];
  2697.          break;
  2698.       case GLX_CONTEXT_PROFILE_MASK_ARB:
  2699.          profileMask = attrib_list[++i];
  2700.          break;
  2701.       case GLX_RENDER_TYPE:
  2702.          renderType = attrib_list[++i];
  2703.          break;
  2704.       case 0:
  2705.          /* end of list */
  2706.          done = True;
  2707.          break;
  2708.       default:
  2709.          /* bad attribute */
  2710.          /* XXX generate BadValue X Error */
  2711.          return NULL;
  2712.       }
  2713.    }
  2714.  
  2715.    /* check contextFlags */
  2716.    if (contextFlags & ~contextFlagsAll) {
  2717.       return NULL; /* generate BadValue X Error */
  2718.    }
  2719.  
  2720.    /* check profileMask */
  2721.    if (profileMask != GLX_CONTEXT_CORE_PROFILE_BIT_ARB &&
  2722.        profileMask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) {
  2723.       return NULL; /* generate BadValue X Error */
  2724.    }
  2725.  
  2726.    /* check version (generate BadMatch if bad) */
  2727.    switch (majorVersion) {
  2728.    case 1:
  2729.       if (minorVersion < 0 || minorVersion > 5)
  2730.          return NULL;
  2731.       break;
  2732.    case 2:
  2733.       if (minorVersion < 0 || minorVersion > 1)
  2734.          return NULL;
  2735.       break;
  2736.    case 3:
  2737.       if (minorVersion < 0 || minorVersion > 2)
  2738.          return NULL;
  2739.       break;
  2740.    case 4:
  2741.       if (minorVersion < 0 || minorVersion > 0)
  2742.          return NULL;
  2743.       break;
  2744.    default:
  2745.       return NULL;
  2746.    }
  2747.  
  2748.    if ((contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
  2749.        majorVersion < 3)
  2750.       return NULL; /* generate GLXBadProfileARB */
  2751.  
  2752.    if (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3)
  2753.       return NULL; /* generate BadMatch */
  2754.  
  2755.    return create_context(dpy, xmvis,
  2756.                          shareCtx ? shareCtx->xmesaContext : NULL,
  2757.                          direct,
  2758.                          majorVersion, minorVersion,
  2759.                          profileMask, contextFlags);
  2760. }
  2761.