home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src / glx.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  44KB  |  1,532 lines

  1. /* $Id: glx.c,v 1.46 1996/05/22 14:12:49 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995-1996  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Log: glx.c,v $
  26.  * Revision 1.46  1996/05/22  14:12:49  brianp
  27.  * added GLX_EXT_visual_info extension
  28.  *
  29.  * Revision 1.45  1996/05/16  14:21:35  brianp
  30.  * added overlay support
  31.  *
  32.  * Revision 1.44  1996/04/26  16:59:27  brianp
  33.  * added the GLX_MESA_pixmap_colormap extension
  34.  *
  35.  * Revision 1.43  1996/04/25  20:49:09  brianp
  36.  * improved handling of stencil, depth, and accum attributes
  37.  *
  38.  * Revision 1.42  1996/02/26  16:33:26  brianp
  39.  * changed version strings to 1.2.7
  40.  *
  41.  * Revision 1.41  1996/01/22  15:31:15  brianp
  42.  * changed version strings to 1.2.6
  43.  *
  44.  * Revision 1.40  1996/01/07  22:50:23  brianp
  45.  * improved glXGetConfig R,G,B,A-SIZE queries
  46.  *
  47.  * Revision 1.39  1995/12/18  17:29:11  brianp
  48.  * use new GLdepth and GLaccum types
  49.  *
  50.  * Revision 1.38  1995/11/30  00:20:20  brianp
  51.  * changed version strings to 1.2.5
  52.  *
  53.  * Revision 1.37  1995/11/20  20:49:47  brianp
  54.  * check for HP color recovery atom before choosing 8-bit Pseudo over TrueColor
  55.  *
  56.  * Revision 1.36  1995/11/03  17:39:08  brianp
  57.  * changed visual->class to visual->c_class for C++
  58.  *
  59.  * Revision 1.35  1995/11/01  15:13:40  brianp
  60.  * renamed all class variables per Steven Spitz
  61.  *
  62.  * Revision 1.34  1995/10/14  16:31:52  brianp
  63.  * don't make copy of XVisualInfo anymore
  64.  * cleaned up some code, bumped version string to 1.2.4
  65.  *
  66.  * Revision 1.33  1995/09/20  18:21:15  brianp
  67.  * support for 4-bit visuals added
  68.  *
  69.  * Revision 1.32  1995/09/15  18:52:32  brianp
  70.  * updated version strings to 1.2.3
  71.  *
  72.  * Revision 1.31  1995/09/05  19:59:17  brianp
  73.  * glXCreateContext() accepts non-glXChooseVisual() visuals per Wolfram Gloger
  74.  *
  75.  * Revision 1.30  1995/09/05  15:35:48  brianp
  76.  * bitcount() was incorrect
  77.  * changed find_glx_visual() to match IDs per Armin Liebchen
  78.  *
  79.  * Revision 1.29  1995/08/24  14:30:08  brianp
  80.  * try to match root visual in get_visual(), per Asif Khan
  81.  * pick 8-bit PseudoColor before 8-bit TrueColor in choose_x_visual()
  82.  *
  83.  * Revision 1.28  1995/08/01  20:56:39  brianp
  84.  * lots of new GL/X visual handling code
  85.  *
  86.  * Revision 1.27  1995/07/24  21:38:36  brianp
  87.  * changed choose_x_visual() to start with 8-bit CI depths
  88.  *
  89.  * Revision 1.26  1995/07/24  20:35:20  brianp
  90.  * replaced memset() with MEMSET() and memcpy() with MEMCPY()
  91.  *
  92.  * Revision 1.25  1995/07/24  18:56:49  brianp
  93.  * added GrayScale and StaticGray support
  94.  * new choose_x_visual() algorithm
  95.  * glXGetConfig(GLX_DEPTH_SIZE) returns bits, not bytes
  96.  *
  97.  * Revision 1.24  1995/07/06  20:14:01  brianp
  98.  * added DirectColor support to glXChooseVisual()
  99.  *
  100.  * Revision 1.23  1995/06/12  15:29:06  brianp
  101.  * search for CI visuals from shallowest to deepest per GLX_BUFFER_SIZE
  102.  *
  103.  * Revision 1.22  1995/06/09  21:48:22  brianp
  104.  * changed version string to 1.2.1
  105.  *
  106.  * Revision 1.21  1995/05/24  13:00:15  brianp
  107.  * updated version query functions to return 1.2
  108.  *
  109.  * Revision 1.20  1995/05/22  21:02:41  brianp
  110.  * Release 1.2
  111.  *
  112.  * Revision 1.19  1995/05/22  16:44:48  brianp
  113.  * added over/underlay error checking
  114.  *
  115.  * Revision 1.18  1995/05/19  14:22:18  brianp
  116.  * added MESA_BACK_BUFFER environment variable
  117.  *
  118.  * Revision 1.17  1995/05/16  19:19:46  brianp
  119.  * added casts to allow compiling with OpenGL's glx.h header
  120.  * implemented GLX_color_SIZE attributes in glXGetConfig()
  121.  *
  122.  * Revision 1.16  1995/05/15  15:48:21  brianp
  123.  * added share_list support to glXCreateContext
  124.  *
  125.  * Revision 1.15  1995/05/10  19:01:29  brianp
  126.  * Better glXGetConfig() support from Armin Liebchen
  127.  *
  128.  * Revision 1.14  1995/04/17  14:40:07  brianp
  129.  * Changed XMesaAttachTo... to XMesaBind...
  130.  *
  131.  * Revision 1.13  1995/04/17  14:31:26  brianp
  132.  * GLXPixmaps implemented
  133.  * uses new XMesaCreateContext() API
  134.  *
  135.  * Revision 1.12  1995/04/13  19:49:12  brianp
  136.  * added SGI's multi-sample extension for GLX 1.1
  137.  *
  138.  * Revision 1.11  1995/04/11  13:40:35  brianp
  139.  * better GLX visual handling
  140.  * introduced GLX 1.1 functions
  141.  *
  142.  * Revision 1.10  1995/03/30  21:09:44  brianp
  143.  * added 8-bit TrueColor test
  144.  *
  145.  * Revision 1.9  1995/03/27  20:33:12  brianp
  146.  * added MESA_RGB_VISUAL, MESA_CI_VISUAL environment variable support
  147.  *
  148.  * Revision 1.8  1995/03/24  15:16:52  brianp
  149.  * replaced ACCUM_BITS with ACC_TYPE
  150.  *
  151.  * Revision 1.7  1995/03/13  15:58:04  brianp
  152.  * removed glXUseXFont stub
  153.  *
  154.  * Revision 1.6  1995/03/08  18:51:21  brianp
  155.  * check if ctx is NULL in glXMakeCurrent per Thorsten Olh
  156.  *
  157.  * Revision 1.5  1995/03/07  19:10:19  brianp
  158.  * look at color/index depth arguments when selecting the visual
  159.  *
  160.  * Revision 1.4  1995/03/04  19:29:44  brianp
  161.  * 1.1 beta revision
  162.  *
  163.  * Revision 1.3  1995/03/04  19:18:17  brianp
  164.  * new visual selection code
  165.  *
  166.  * Revision 1.2  1995/03/01  17:05:00  brianp
  167.  * added error check to glXSwapBuffers
  168.  *
  169.  * Revision 1.1  1995/02/28  21:23:25  brianp
  170.  * Initial revision
  171.  *
  172.  */
  173.  
  174.  
  175. /*
  176.  * A pseudo-GLX implementation to allow OpenGL/GLX programs to work with Mesa.
  177.  *
  178.  * Thanks to the contributors:
  179.  *
  180.  * Initial version:  Philip Brown (philb@CSUA.Berkeley.EDU)
  181.  * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
  182.  * Further visual-handling refinements: Wolfram Gloger
  183.  *    (wmglo@Dent.MED.Uni-Muenchen.DE).
  184.  */
  185.  
  186.  
  187.  
  188. #include <stdio.h>
  189. #include <stdlib.h>
  190. #include <string.h>
  191. #include <X11/Xlib.h>
  192. #include <X11/Xutil.h>
  193. #include "GL/gl.h"
  194. #include "GL/glx.h"
  195. #include "GL/xmesa.h"
  196. #include "xmesaP.h"
  197. #include "config.h"
  198. #include "context.h"
  199. #include "dd.h"
  200. #include "macros.h"
  201.  
  202.  
  203. #define DONT_CARE -1
  204.  
  205.  
  206.  
  207. /*
  208.  * Since we don't have a real GLX extension, the XVisualInfo doesn't
  209.  * carry all the info we need such as double buffer mode, depth buffer, etc.
  210.  * We use a table to associate this extra information with each XVisualInfo
  211.  * structure we encounter in glXChooseVisual() or glXGetConfig().
  212.  */
  213. struct glx_visual {
  214.     Display *dpy;
  215.     XVisualInfo *visinfo;        /* The X information */
  216.     GLboolean rgb_flag;        /* RGBA mode? */
  217.         GLboolean alpha_flag;        /* alpha buffer? */
  218.         GLboolean double_flag;        /* double buffer? */
  219.         GLint depth_size;
  220.         GLint stencil_size;
  221.         GLint accum_size;
  222.         GLint level;            /* 0=normal, 1=overlay, etc */
  223. };
  224.  
  225. #define MAX_VISUALS 100
  226.  
  227. static struct glx_visual VisualTable[MAX_VISUALS];
  228. static int NumVisuals = 0;
  229.  
  230.  
  231.  
  232. /*
  233.  * We also need to keep a list of Pixmaps created with glXCreateGLXPixmap()
  234.  * so when glXMakeCurrent() is called we know if the drawable is a pixmap
  235.  * or a window.
  236.  */
  237. struct glx_pixmap {
  238.     Pixmap pixmap;
  239.     Colormap cmap;
  240. };
  241.  
  242. #define MAX_PIXMAPS 10
  243. static struct glx_pixmap PixmapList[MAX_PIXMAPS];
  244. static int NumPixmaps = 0;
  245.  
  246.  
  247.  
  248. /*
  249.  * This struct and some code fragments borrowed
  250.  * from Mark Kilgard's GLUT library.
  251.  */
  252. typedef struct _OverlayInfo {
  253.   /* Avoid 64-bit portability problems by being careful to use
  254.      longs due to the way XGetWindowProperty is specified. Note
  255.      that these parameters are passed as CARD32s over X
  256.      protocol. */
  257.   long overlay_visual;
  258.   long transparent_type;
  259.   long value;
  260.   long layer;
  261. } OverlayInfo;
  262.  
  263.  
  264.  
  265. /* Macro to handle c_class vs class field name in XVisualInfo struct */
  266. #if defined(__cplusplus) || defined(c_plusplus)
  267. #define CLASS c_class
  268. #else
  269. #define CLASS class
  270. #endif
  271.  
  272.  
  273.  
  274. /*
  275.  * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
  276.  * configuration in our list of GLX visuals.
  277.  */
  278. static struct glx_visual *
  279. save_glx_visual( Display *dpy, XVisualInfo *vinfo,
  280.                  GLboolean rgb, GLboolean alpha, GLboolean dbl,
  281.                  GLint depth_size, GLint stencil_size,
  282.                  GLint accum_size, GLint level )
  283. {
  284.    if (NumVisuals+1<MAX_VISUALS) {
  285.       VisualTable[NumVisuals].dpy = dpy;
  286.       VisualTable[NumVisuals].visinfo = vinfo;
  287.       VisualTable[NumVisuals].rgb_flag = rgb;
  288.       VisualTable[NumVisuals].alpha_flag = alpha;
  289.       VisualTable[NumVisuals].double_flag = dbl;
  290.       VisualTable[NumVisuals].depth_size = depth_size;
  291.       VisualTable[NumVisuals].stencil_size = stencil_size;
  292.       VisualTable[NumVisuals].accum_size = accum_size;
  293.       VisualTable[NumVisuals].level = level;
  294.       NumVisuals++;
  295.       return &VisualTable[NumVisuals-1];
  296.    }
  297.    else {
  298.       fprintf( stderr, "GLX Error: maximum number of visuals exceeded\n");
  299.       return NULL;
  300.    }
  301. }
  302.  
  303.  
  304.  
  305. /*
  306.  * Find the GLX visual associated with an XVisualInfo then return the
  307.  * RGBA, double-buffering, and depth-buffer flags.
  308.  */
  309. static struct glx_visual *
  310. find_glx_visual( Display *dpy, XVisualInfo *vinfo )
  311. {
  312.    int i;
  313.  
  314.    /* First try to match pointers */
  315.    for (i=0;i<NumVisuals;i++) {
  316.       if (VisualTable[i].dpy==dpy && VisualTable[i].visinfo==vinfo) {
  317.          return &VisualTable[i];
  318.       }
  319.    }
  320.    /* try to match visual id */
  321.    for (i=0;i<NumVisuals;i++) {
  322.       if (VisualTable[i].dpy==dpy
  323.           && VisualTable[i].visinfo->visualid == vinfo->visualid) {
  324.          return &VisualTable[i];
  325.       }
  326.    }
  327.    return NULL;
  328. }
  329.  
  330.  
  331.  
  332. /*
  333.  * Test if the given XVisualInfo is usable for Mesa rendering.
  334.  */
  335. static GLboolean is_usable_visual( XVisualInfo *vinfo )
  336. {
  337.    switch (vinfo->CLASS) {
  338.       case StaticGray:
  339.       case GrayScale:
  340.          /* Any StaticGray/GrayScale visual works in RGB or CI mode */
  341.          return GL_TRUE;
  342.       case StaticColor:
  343.       case PseudoColor:
  344.      /* Any StaticColor/PseudoColor visual of at least 4 bits */
  345.      if (vinfo->depth>=4) {
  346.         return GL_TRUE;
  347.      }
  348.      else {
  349.         return GL_FALSE;
  350.      }
  351.       case TrueColor:
  352.       case DirectColor:
  353.      /* Any depth of TrueColor or DirectColor works in RGB mode */
  354.      return GL_TRUE;
  355.       default:
  356.      /* This should never happen */
  357.      return GL_FALSE;
  358.    }
  359. }
  360.  
  361.  
  362.  
  363. /*
  364.  * Test if the given XVisualInfo is an over/underlay visual.
  365.  * Input:  dpy - the X display
  366.  *         vinfo - the XVisualInfo to test
  367.  * Output:  level - the level of the visual if it is an over/underlay
  368.  */
  369. static GLboolean is_overlay_visual( Display *dpy, XVisualInfo *vinfo,
  370.                                     int *level )
  371. {
  372.    Atom overlayVisualsAtom;
  373.    OverlayInfo *overlay_info;
  374.    int numOverlaysPerScreen;
  375.    Status status;
  376.    Atom actualType;
  377.    int actualFormat;
  378.    unsigned long sizeData, bytesLeft;
  379.    int i;
  380.  
  381.    /*
  382.     * The SERVER_OVERLAY_VISUALS property on the root window contains
  383.     * a list of overlay visuals.  Get that list now.
  384.     */
  385.    overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
  386.    if (overlayVisualsAtom == None) {
  387.       return GL_FALSE;
  388.    }
  389.  
  390.    status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
  391.                                overlayVisualsAtom, 0L, (long) 10000, False,
  392.                                overlayVisualsAtom, &actualType, &actualFormat,
  393.                                &sizeData, &bytesLeft,
  394.                                (unsigned char **) &overlay_info );
  395.  
  396.    if (status != Success || actualType != overlayVisualsAtom ||
  397.        actualFormat != 32 || sizeData < 4) {
  398.       /* something went wrong */
  399.       return GL_FALSE;
  400.    }
  401.  
  402.    /* search the overlay visual list for the visual ID of interest */
  403.    numOverlaysPerScreen = sizeData / 4;
  404.    for (i=0;i<numOverlaysPerScreen;i++) {
  405.       OverlayInfo *ov;
  406.       ov = overlay_info + i;
  407.       if (ov->overlay_visual==vinfo->visualid) {
  408.          /* found the visual */
  409.          if (/*ov->transparent_type==1 &&*/ ov->layer!=0) {
  410.             *level = ov->layer;
  411.             return GL_TRUE;
  412.          }
  413.          else {
  414.             return GL_FALSE;
  415.          }
  416.       }
  417.    }
  418.  
  419.    /* The visual ID was not found in the overlay list. */
  420.    return GL_FALSE;
  421. }
  422.  
  423.  
  424.  
  425. /*
  426.  * Return the transparent pixel value for a GLX visual.
  427.  * Input:  glvis - the glx_visual
  428.  * Return:  a pixel value or -1 if no transparent pixel
  429.  */
  430. static int transparent_pixel( struct glx_visual *glvis )
  431. {
  432.    Display *dpy = glvis->dpy;
  433.    XVisualInfo *vinfo = glvis->visinfo;
  434.    Atom overlayVisualsAtom;
  435.    OverlayInfo *overlay_info;
  436.    int numOverlaysPerScreen;
  437.    Status status;
  438.    Atom actualType;
  439.    int actualFormat;
  440.    unsigned long sizeData, bytesLeft;
  441.    int i;
  442.  
  443.    /*
  444.     * The SERVER_OVERLAY_VISUALS property on the root window contains
  445.     * a list of overlay visuals.  Get that list now.
  446.     */
  447.    overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
  448.    if (overlayVisualsAtom == None) {
  449.       return -1;
  450.    }
  451.  
  452.    status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
  453.                                overlayVisualsAtom, 0L, (long) 10000, False,
  454.                                overlayVisualsAtom, &actualType, &actualFormat,
  455.                                &sizeData, &bytesLeft,
  456.                                (unsigned char **) &overlay_info );
  457.  
  458.    if (status != Success || actualType != overlayVisualsAtom ||
  459.        actualFormat != 32 || sizeData < 4) {
  460.       /* something went wrong */
  461.       return -1;
  462.    }
  463.  
  464.    /* search the overlay visual list for the visual ID of interest */
  465.    numOverlaysPerScreen = sizeData / 4;
  466.    for (i=0;i<numOverlaysPerScreen;i++) {
  467.       OverlayInfo *ov;
  468.       ov = overlay_info + i;
  469.       if (ov->overlay_visual==vinfo->visualid) {
  470.          /* found it! */
  471.          if (ov->transparent_type==0) {
  472.             /* type 0 indicates no transparency */
  473.             return -1;
  474.          }
  475.          else {
  476.             /* ov->value is the transparent pixel */
  477.             return ov->value;
  478.          }
  479.       }
  480.    }
  481.  
  482.    /* The visual ID was not found in the overlay list. */
  483.    return -1;
  484. }
  485.  
  486.  
  487.  
  488. /*
  489.  * Try to get an X visual which matches the given arguments.
  490.  */
  491. static XVisualInfo *get_visual( Display *dpy, int scr,
  492.                     unsigned int depth, int xclass )
  493. {
  494.    XVisualInfo temp;
  495.    long mask;
  496.    int n;
  497.    int default_depth;
  498.    int default_class;
  499.  
  500.    mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
  501.    temp.screen = scr;
  502.    temp.depth = depth;
  503.    temp.CLASS = xclass;
  504.  
  505.    default_depth = DefaultDepth(dpy,scr);
  506.    default_class = DefaultVisual(dpy,scr)->CLASS;
  507.  
  508.    if (depth==default_depth && xclass==default_class) {
  509.       /* try to get root window's visual */
  510.       temp.visualid = DefaultVisual(dpy,scr)->visualid;
  511.       mask |= VisualIDMask;
  512.    }
  513.  
  514.    return XGetVisualInfo( dpy, mask, &temp, &n );
  515. }
  516.  
  517.  
  518.  
  519. /*
  520.  * Retrieve the value of the given environment variable and find
  521.  * the X visual which matches it.
  522.  * Input:  dpy - the display
  523.  *         screen - the screen number
  524.  *         varname - the name of the environment variable
  525.  * Return:  an XVisualInfo pointer to NULL if error.
  526.  */
  527. static XVisualInfo *get_env_visual( Display *dpy, int scr, char *varname )
  528. {
  529.    char *value;
  530.    char type[100];
  531.    int depth, xclass = -1;
  532.    XVisualInfo *vis;
  533.  
  534.    value = getenv( varname );
  535.    if (!value) {
  536.       return NULL;
  537.    }
  538.  
  539.    sscanf( value, "%s %d", type, &depth );
  540.  
  541.    if (strcmp(type,"TrueColor")==0)          xclass = TrueColor;
  542.    else if (strcmp(type,"DirectColor")==0)   xclass = DirectColor;
  543.    else if (strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
  544.    else if (strcmp(type,"StaticColor")==0)   xclass = StaticColor;
  545.    else if (strcmp(type,"GrayScale")==0)     xclass = GrayScale;
  546.    else if (strcmp(type,"StaticGray")==0)    xclass = StaticGray;
  547.  
  548.    if (xclass>-1 && depth>0) {
  549.       vis = get_visual( dpy, scr, depth, xclass );
  550.       if (vis) {
  551.      return vis;
  552.       }
  553.    }
  554.  
  555.    fprintf( stderr, "Mesa: GLX unable to find visual class=%s, depth=%d.\n",
  556.         type, depth );
  557.    return NULL;
  558. }
  559.  
  560.  
  561.  
  562. /*
  563.  * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
  564.  * Input:  dpy, screen - X display and screen number
  565.  *         rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
  566.  *         min_depth - minimum visual depth
  567.  *         preferred_class - preferred GLX visual class or DONT_CARE
  568.  * Return:  pointer to an XVisualInfo or NULL.
  569.  */
  570. static XVisualInfo *choose_x_visual( Display *dpy, int screen,
  571.                      GLboolean rgba, int min_depth,
  572.                                      int preferred_class )
  573. {
  574.    XVisualInfo *vis;
  575.    int xclass, visclass;
  576.    int depth;
  577.  
  578.    if (rgba) {
  579.       Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
  580.       /* First see if the MESA_RGB_VISUAL env var is defined */
  581.       vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
  582.       if (vis) {
  583.      return vis;
  584.       }
  585.       /* Otherwise, search for a suitable visual */
  586.       if (preferred_class==DONT_CARE) {
  587.          for (xclass=0;xclass<6;xclass++) {
  588.             switch (xclass) {
  589.                case 0:  visclass = TrueColor;    break;
  590.                case 1:  visclass = DirectColor;  break;
  591.                case 2:  visclass = PseudoColor;  break;
  592.                case 3:  visclass = StaticColor;  break;
  593.                case 4:  visclass = GrayScale;    break;
  594.                case 5:  visclass = StaticGray;   break;
  595.             }
  596.             if (min_depth==0) {
  597.                /* start with shallowest */
  598.                for (depth=0;depth<=24;depth++) {
  599.                   if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
  600.                      /* Special case:  try to get 8-bit PseudoColor before */
  601.                      /* 8-bit TrueColor */
  602.                      vis = get_visual( dpy, screen, 8, PseudoColor );
  603.                      if (vis) {
  604.                         return vis;
  605.                      }
  606.                   }
  607.                   vis = get_visual( dpy, screen, depth, visclass );
  608.                   if (vis) {
  609.                      return vis;
  610.                   }
  611.                }
  612.             }
  613.             else {
  614.                /* start with deepest */
  615.                for (depth=24;depth>=min_depth;depth--) {
  616.                   if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
  617.                      /* Special case:  try to get 8-bit PseudoColor before */
  618.                      /* 8-bit TrueColor */
  619.                      vis = get_visual( dpy, screen, 8, PseudoColor );
  620.                      if (vis) {
  621.                         return vis;
  622.                      }
  623.                   }
  624.                   vis = get_visual( dpy, screen, depth, visclass );
  625.                   if (vis) {
  626.                      return vis;
  627.                   }
  628.                }
  629.             }
  630.          }
  631.       }
  632.       else {
  633.          /* search for a specific visual class */
  634.          switch (preferred_class) {
  635.             case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
  636.             case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
  637.             case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
  638.             case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
  639.             case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
  640.             case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
  641.             default:   return NULL;
  642.          }
  643.          if (min_depth==0) {
  644.             /* start with shallowest */
  645.             for (depth=0;depth<=24;depth++) {
  646.                vis = get_visual( dpy, screen, depth, visclass );
  647.                if (vis) {
  648.                   return vis;
  649.                }
  650.             }
  651.          }
  652.          else {
  653.             /* start with deepest */
  654.             for (depth=24;depth>=min_depth;depth--) {
  655.                vis = get_visual( dpy, screen, depth, visclass );
  656.                if (vis) {
  657.                   return vis;
  658.                }
  659.             }
  660.          }
  661.       }
  662.    }
  663.    else {
  664.       /* First see if the MESA_CI_VISUAL env var is defined */
  665.       vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
  666.       if (vis) {
  667.      return vis;
  668.       }
  669.       /* Otherwise, search for a suitable visual, starting with shallowest */
  670.       if (preferred_class==DONT_CARE) {
  671.          for (xclass=0;xclass<4;xclass++) {
  672.             switch (xclass) {
  673.                case 0:  visclass = PseudoColor;  break;
  674.                case 1:  visclass = StaticColor;  break;
  675.                case 2:  visclass = GrayScale;    break;
  676.                case 3:  visclass = StaticGray;   break;
  677.             }
  678.             /* try 8-bit up through 16-bit */
  679.             for (depth=8;depth<=16;depth++) {
  680.                vis = get_visual( dpy, screen, depth, visclass );
  681.                if (vis) {
  682.                   return vis;
  683.                }
  684.             }
  685.             /* try min_depth up to 8-bit */
  686.             for (depth=min_depth;depth<8;depth++) {
  687.                vis = get_visual( dpy, screen, depth, visclass );
  688.                if (vis) {
  689.                   return vis;
  690.                }
  691.             }
  692.          }
  693.       }
  694.       else {
  695.          /* search for a specific visual class */
  696.          switch (preferred_class) {
  697.             case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
  698.             case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
  699.             case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
  700.             case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
  701.             case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
  702.             case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
  703.             default:   return NULL;
  704.          }
  705.          /* try 8-bit up through 16-bit */
  706.          for (depth=8;depth<=16;depth++) {
  707.             vis = get_visual( dpy, screen, depth, visclass );
  708.             if (vis) {
  709.                return vis;
  710.             }
  711.          }
  712.          /* try min_depth up to 8-bit */
  713.          for (depth=min_depth;depth<8;depth++) {
  714.             vis = get_visual( dpy, screen, depth, visclass );
  715.             if (vis) {
  716.                return vis;
  717.             }
  718.          }
  719.       }
  720.    }
  721.  
  722.    /* didn't find a visual */
  723.    return NULL;
  724. }
  725.  
  726.  
  727.  
  728. /*
  729.  * Find the deepest X over/underlay visual of at least min_depth.
  730.  * Input:  dpy, screen - X display and screen number
  731.  *         level - the over/underlay level
  732.  *         trans_type - transparent pixel type: GLX_NONE_EXT,
  733.  *                      GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
  734.  *                      or DONT_CARE
  735.  *         trans_value - transparent pixel value or DONT_CARE
  736.  *         min_depth - minimum visual depth
  737.  *         preferred_class - preferred GLX visual class or DONT_CARE
  738.  * Return:  pointer to an XVisualInfo or NULL.
  739.  */
  740. static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr,
  741.                                              int level, int trans_type,
  742.                                              int trans_value,
  743.                                              int min_depth,
  744.                                              int preferred_class )
  745. {
  746.    Atom overlayVisualsAtom;
  747.    OverlayInfo *overlay_info;
  748.    int numOverlaysPerScreen;
  749.    Status status;
  750.    Atom actualType;
  751.    int actualFormat;
  752.    unsigned long sizeData, bytesLeft;
  753.    int i;
  754.    XVisualInfo *deepvis;
  755.    int deepest;
  756.  
  757.    /*TMP*/ int tt, tv;
  758.  
  759.    switch (preferred_class) {
  760.       case GLX_TRUE_COLOR_EXT:    preferred_class = TrueColor;    break;
  761.       case GLX_DIRECT_COLOR_EXT:  preferred_class = DirectColor;  break;
  762.       case GLX_PSEUDO_COLOR_EXT:  preferred_class = PseudoColor;  break;
  763.       case GLX_STATIC_COLOR_EXT:  preferred_class = StaticColor;  break;
  764.       case GLX_GRAY_SCALE_EXT:    preferred_class = GrayScale;    break;
  765.       case GLX_STATIC_GRAY_EXT:   preferred_class = StaticGray;   break;
  766.       default:                    preferred_class = DONT_CARE;
  767.    }
  768.  
  769.    /*
  770.     * The SERVER_OVERLAY_VISUALS property on the root window contains
  771.     * a list of overlay visuals.  Get that list now.
  772.     */
  773.    overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
  774.    if (overlayVisualsAtom == None) {
  775.       return GL_FALSE;
  776.    }
  777.  
  778.    status = XGetWindowProperty(dpy, RootWindow( dpy, scr ),
  779.                                overlayVisualsAtom, 0L, (long) 10000, False,
  780.                                overlayVisualsAtom, &actualType, &actualFormat,
  781.                                &sizeData, &bytesLeft,
  782.                                (unsigned char **) &overlay_info );
  783.  
  784.    if (status != Success || actualType != overlayVisualsAtom ||
  785.        actualFormat != 32 || sizeData < 4) {
  786.       /* something went wrong */
  787.       return GL_FALSE;
  788.    }
  789.  
  790.    /* Search for the deepest overlay which satisifies all criteria. */
  791.    deepest = min_depth;
  792.    deepvis = NULL;
  793.  
  794.    numOverlaysPerScreen = sizeData / 4;
  795.    for (i=0;i<numOverlaysPerScreen;i++) {
  796.       XVisualInfo *vislist, template;
  797.       int count;
  798.       OverlayInfo *ov;
  799.       ov = overlay_info + i;
  800.  
  801.       if (ov->layer!=level) {
  802.          /* failed overlay level criteria */
  803.          continue;
  804.       }
  805.       if (!(trans_type==DONT_CARE
  806.             || (trans_type==GLX_TRANSPARENT_INDEX_EXT
  807.                 && ov->transparent_type>0)
  808.             || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
  809.          /* failed transparent pixel type criteria */
  810.          continue;
  811.       }
  812.       if (trans_value!=DONT_CARE && trans_value!=ov->value) {
  813.          /* failed transparent pixel value criteria */
  814.          continue;
  815.       }
  816.  
  817.       /* get XVisualInfo and check the depth */
  818.       template.visualid = ov->overlay_visual;
  819.       template.screen = scr;
  820.       vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
  821.                                 &template, &count );
  822.  
  823.       if (count!=1) {
  824.          /* something went wrong */
  825.          continue;
  826.       }
  827.       if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
  828.          /* wrong visual class */
  829.          continue;
  830.       }
  831.  
  832.       if (deepvis==NULL || vislist->depth > deepest) {
  833.          /* YES!  found a satisfactory visual */
  834.          if (deepvis) {
  835.             free( deepvis );
  836.          }
  837.          deepest = vislist->depth;
  838.          deepvis = vislist;
  839.          /* TMP */  tt = ov->transparent_type;
  840.          /* TMP */  tv = ov->value;
  841.       }
  842.    }
  843.  
  844. /*TMP
  845.    if (deepvis) {
  846.       printf("chose 0x%x:  layer=%d depth=%d trans_type=%d trans_value=%d\n",
  847.              deepvis->visualid, level, deepvis->depth, tt, tv );
  848.    }
  849. */
  850.    return deepvis;
  851. }
  852.  
  853.  
  854.  
  855. /*
  856.  * Return the number of bits set in n.
  857.  */
  858. static int bitcount( unsigned long n )
  859. {
  860.    int bits;
  861.    for (bits=0; n>0; n=n>>1) {
  862.       if (n&1) {
  863.          bits++;
  864.       }
  865.    }
  866.    return bits;
  867. }
  868.  
  869.  
  870.  
  871. XVisualInfo *glXChooseVisual( Display *dpy, int screen, int *list )
  872. {
  873.    int *parselist;
  874.    XVisualInfo *vis;
  875.    int min_depth = 0;
  876.    int min_ci = 0;
  877.    int min_red=0, min_green=0, min_blue=0, min_alpha=0;
  878.    GLboolean rgb_flag = GL_FALSE;
  879.    GLboolean alpha_flag = GL_FALSE;
  880.    GLboolean double_flag = GL_FALSE;
  881.    GLint depth_size = 0;
  882.    GLint stencil_size = 0;
  883.    GLint accum_size = 0;
  884.    int level = 0;
  885.    int visual_type = DONT_CARE;
  886.    int trans_type = DONT_CARE;
  887.    int trans_value = DONT_CARE;
  888.  
  889.    parselist = list;
  890.  
  891.    while (*parselist) {
  892.  
  893.       switch (*parselist) {
  894.      case GLX_USE_GL:
  895.         /* ignore */
  896.         parselist++;
  897.         break;
  898.      case GLX_BUFFER_SIZE:
  899.         parselist++;
  900.         min_ci = *parselist++;
  901.         break;
  902.      case GLX_LEVEL:
  903.         parselist++;
  904.             level = *parselist++;
  905.         break;
  906.      case GLX_RGBA:
  907.         rgb_flag = GL_TRUE;
  908.         parselist++;
  909.         break;
  910.      case GLX_DOUBLEBUFFER:
  911.         double_flag = GL_TRUE;
  912.         parselist++;
  913.         break;
  914.      case GLX_STEREO:
  915.         /* not supported */
  916.             return NULL;
  917.         break;
  918.      case GLX_AUX_BUFFERS:
  919.         /* ignore */
  920.         parselist++;
  921.         parselist++;
  922.         break;
  923.      case GLX_RED_SIZE:
  924.         parselist++;
  925.         min_red = *parselist++;
  926.         break;
  927.      case GLX_GREEN_SIZE:
  928.         parselist++;
  929.         min_green = *parselist++;
  930.         break;
  931.      case GLX_BLUE_SIZE:
  932.         parselist++;
  933.         min_blue = *parselist++;
  934.         break;
  935.      case GLX_ALPHA_SIZE:
  936.         parselist++;
  937.             {
  938.                GLint size = *parselist++;
  939.                alpha_flag = size>0 ? 1 : 0;
  940.             }
  941.         break;
  942.      case GLX_DEPTH_SIZE:
  943.         parselist++;
  944.         depth_size = *parselist++;
  945.         break;
  946.      case GLX_STENCIL_SIZE:
  947.         parselist++;
  948.         stencil_size = *parselist++;
  949.         break;
  950.      case GLX_ACCUM_RED_SIZE:
  951.      case GLX_ACCUM_GREEN_SIZE:
  952.      case GLX_ACCUM_BLUE_SIZE:
  953.      case GLX_ACCUM_ALPHA_SIZE:
  954.         parselist++;
  955.             {
  956.                GLint size = *parselist++;
  957.                accum_size = MAX2( accum_size, size );
  958.             }
  959.         break;
  960.  
  961.          /*
  962.           * GLX_EXT_visual_info extension
  963.           */
  964.          case GLX_X_VISUAL_TYPE_EXT:
  965.             parselist++;
  966.             visual_type = *parselist++;
  967.             break;
  968.          case GLX_TRANSPARENT_TYPE_EXT:
  969.             parselist++;
  970.             trans_type = *parselist++;
  971.             break;
  972.          case GLX_TRANSPARENT_INDEX_VALUE_EXT:
  973.             parselist++;
  974.             trans_value = *parselist++;
  975.             break;
  976.          case GLX_TRANSPARENT_RED_VALUE_EXT:
  977.          case GLX_TRANSPARENT_GREEN_VALUE_EXT:
  978.          case GLX_TRANSPARENT_BLUE_VALUE_EXT:
  979.          case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
  980.         /* ignore */
  981.         parselist++;
  982.         parselist++;
  983.         break;
  984.          
  985.      case None:
  986.         break;
  987.      default:
  988.         /* undefined attribute */
  989.         return NULL;
  990.       }
  991.    }
  992.  
  993.    /*
  994.     * Since we're only simulating the GLX extension this function will never
  995.     * find any real GL visuals.  Instead, all we can do is try to find an RGB
  996.     * or CI visual of appropriate depth.  Other requested attributes such as
  997.     * double buffering, depth buffer, etc. will be associated with the X
  998.     * visual and stored in the VisualTable[].
  999.     */
  1000.    if (level==0) {
  1001.       /* normal color planes */
  1002.       if (rgb_flag) {
  1003.          /* Get an RGB visual */
  1004.          int min_rgb = min_red + min_green + min_blue;
  1005.          if (min_rgb>1 && min_rgb<8) {
  1006.             /* a special case to be sure we can get a monochrome visual */
  1007.             min_rgb = 1;
  1008.          }
  1009.          vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
  1010.       }
  1011.       else {
  1012.          /* Get a color index visual */
  1013.          vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
  1014.          accum_size = 0;
  1015.       }
  1016.    }
  1017.    else {
  1018.       /* over/underlay planes */
  1019.       vis = choose_x_overlay_visual( dpy, screen, level, trans_type,
  1020.                                      trans_value, min_ci, visual_type );
  1021.    }
  1022.  
  1023.    if (vis) {
  1024.       (void) save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
  1025.                               depth_size, stencil_size, accum_size, level );
  1026.    }
  1027.  
  1028.    return vis;
  1029. }
  1030.  
  1031.  
  1032.  
  1033.  
  1034. GLXContext glXCreateContext( Display *dpy, XVisualInfo *visinfo,
  1035.                  GLXContext share_list, Bool direct )
  1036. {
  1037.    XMesaContext ctx;
  1038.    GLboolean ximage_flag = GL_TRUE;
  1039.    struct glx_visual *glvis;
  1040.  
  1041.    glvis = find_glx_visual(dpy, visinfo );
  1042.    if (!glvis) {
  1043.       /* This visual wasn't found with glXChooseVisual() */
  1044.       int vislevel;
  1045.       if (is_overlay_visual( dpy, visinfo, &vislevel )) {
  1046.          /* Configure this visual as a CI, single-buffered overlay */
  1047.          glvis = save_glx_visual( dpy, visinfo,
  1048.                                   GL_FALSE,  /* rgb */
  1049.                                   GL_FALSE,  /* alpha */
  1050.                                   GL_FALSE,  /* double */
  1051.                                   0,         /* depth bits */
  1052.                                   0,         /* stencil bits */
  1053.                                   0,         /* accum bits */
  1054.                                   vislevel   /* level */
  1055.                                 );
  1056.       }
  1057.       else if (is_usable_visual( visinfo )) {
  1058.          /* Configure this visual as RGB, double-buffered, depth-buffered. */
  1059.          /* This is surely wrong for some people's needs but what else */
  1060.          /* can be done?  They should use glXChooseVisual(). */
  1061.          glvis = save_glx_visual( dpy, visinfo,
  1062.                                   GL_TRUE,   /* rgb */
  1063.                                   GL_FALSE,  /* alpha */
  1064.                                   GL_TRUE,   /* double */
  1065.                                   8*sizeof(GLdepth),
  1066.                                   8*sizeof(GLstencil),
  1067.                                   8*sizeof(GLaccum),
  1068.                                   0          /* level */
  1069.                                 );
  1070.       }
  1071.       else {
  1072.          fprintf(stderr,"Mesa: error in glXCreateContext: bad visual\n");
  1073.          return NULL;
  1074.       }
  1075.    }
  1076.  
  1077.    if (glvis->double_flag) {
  1078.       /* Check if the MESA_BACK_BUFFER env var is set */
  1079.       char *backbuffer = getenv("MESA_BACK_BUFFER");
  1080.       if (backbuffer) {
  1081.          if (backbuffer[0]=='p' || backbuffer[0]=='P') {
  1082.             ximage_flag = GL_FALSE;
  1083.          }
  1084.          else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
  1085.             ximage_flag = GL_TRUE;
  1086.          }
  1087.          else {
  1088.             fprintf(stderr, "Mesa: invalid value for MESA_BACK_BUFFER ");
  1089.             fprintf(stderr, "environment variable, using an XImage.\n");
  1090.          }
  1091.       }
  1092.    }
  1093.  
  1094.    ctx = XMesaCreateContext( dpy, visinfo,
  1095.                              glvis->rgb_flag,
  1096.                              glvis->alpha_flag,
  1097.                              glvis->double_flag,
  1098.                              glvis->depth_size,
  1099.                              glvis->stencil_size,
  1100.                              glvis->accum_size,
  1101.                  ximage_flag, (XMesaContext) share_list );
  1102.  
  1103.    return (GLXContext) ctx;
  1104. }
  1105.  
  1106.  
  1107.  
  1108. Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
  1109. {
  1110.    if (ctx && drawable) {
  1111.       /* determine if the drawable is a GLXPixmap */
  1112.       GLuint i;
  1113.       GLboolean pixmap_flag = GL_FALSE;
  1114.       Colormap cmap;
  1115.       for (i=0;i<NumPixmaps;i++) {
  1116.      if (PixmapList[i].pixmap==drawable) {
  1117.         cmap = PixmapList[i].cmap;
  1118.         pixmap_flag = GL_TRUE;
  1119.         break;
  1120.      }
  1121.       }
  1122.       /* Bind the XMesaContext to the pixmap or window */
  1123.       if (pixmap_flag) {
  1124.      if (!XMesaBindPixmap( (XMesaContext) ctx, drawable, cmap )) {
  1125.         return False;
  1126.      }
  1127.       }
  1128.       else {
  1129.      if (!XMesaBindWindow( (XMesaContext) ctx, drawable )) {
  1130.         return False;
  1131.      }
  1132.       }
  1133.       /* Make the XMesaContext the current one */
  1134.       if (XMesaMakeCurrent( (XMesaContext) ctx )) {
  1135.      return True;
  1136.       }
  1137.       else {
  1138.      return False;
  1139.       }
  1140.    }
  1141.    else if (!ctx && !drawable) {
  1142.       /* release current context w/out assigning new one. */
  1143.       XMesaMakeCurrent( NULL );
  1144.       return True;
  1145.    }
  1146.    else {
  1147.       /* either ctx or drawable is NULL, this is an error */
  1148.       return False;
  1149.    }
  1150. }
  1151.  
  1152.  
  1153.  
  1154. GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visual,
  1155.                               Pixmap pixmap )
  1156. {
  1157.    if (NumPixmaps==MAX_PIXMAPS) {
  1158.       fprintf( stderr, "Mesa: glXCreateGLXPixmap: too many pixmaps\n");
  1159.       return 0;
  1160.    }
  1161.    PixmapList[NumPixmaps].pixmap = pixmap;
  1162.    PixmapList[NumPixmaps].cmap = 0;
  1163.    NumPixmaps++;
  1164.    return pixmap;
  1165. }
  1166.  
  1167.  
  1168. #ifdef GLX_MESA_pixmap_colormap
  1169.  
  1170. GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
  1171.                                   Pixmap pixmap, Colormap cmap )
  1172. {
  1173.    if (NumPixmaps==MAX_PIXMAPS) {
  1174.       fprintf( stderr, "Mesa: glXCreateGLXPixmap: too many pixmaps\n");
  1175.       return 0;
  1176.    }
  1177.    PixmapList[NumPixmaps].pixmap = pixmap;
  1178.    PixmapList[NumPixmaps].cmap = cmap;
  1179.    NumPixmaps++;
  1180.    return pixmap;
  1181. }
  1182.  
  1183. #endif
  1184.  
  1185.  
  1186. void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
  1187. {
  1188.    int i, j;
  1189.  
  1190.    for (i=0;i<NumPixmaps;i++) {
  1191.       if (PixmapList[i].pixmap==pixmap) {
  1192.      for (j=i+1;j<MAX_PIXMAPS;j++) {
  1193.         PixmapList[j-1] = PixmapList[j];
  1194.      }
  1195.      NumPixmaps--;
  1196.      return;
  1197.       }
  1198.    }
  1199.    fprintf( stderr, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
  1200. }
  1201.  
  1202.  
  1203. void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
  1204.              GLuint mask )
  1205. {
  1206.    XMesaContext xm_src, xm_dst;
  1207.    xm_src = (XMesaContext) src;
  1208.    xm_dst = (XMesaContext) dst;
  1209.    gl_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, mask );
  1210. }
  1211.  
  1212.  
  1213.  
  1214. Bool glXQueryExtension( Display *dpy, int *errorb, int *event )
  1215. {
  1216.    /* Mesa's GLX isn't really an X extension but we try to act like one. */
  1217.    return True;
  1218. }
  1219.  
  1220.  
  1221. void glXDestroyContext( Display *dpy, GLXContext ctx )
  1222. {
  1223.    XMesaDestroyContext( (XMesaContext) ctx );
  1224. }
  1225.  
  1226.  
  1227.  
  1228. Bool glXIsDirect( Display *dpy, GLXContext ctx )
  1229. {
  1230.    /* This isn't true but... */
  1231.    return True;
  1232. }
  1233.  
  1234.  
  1235.  
  1236. void glXSwapBuffers( Display *dpy, GLXDrawable drawable )
  1237. {
  1238.    XMesaContext ctx = XMesaGetCurrentContext();
  1239.    if (ctx->frontbuffer!=drawable) {
  1240.       fprintf( stderr,
  1241.       "Warning: glXSwapBuffers drawable doesn't match current context\n");
  1242.    }
  1243.    else {
  1244.       XMesaSwapBuffers();
  1245.    }
  1246. }
  1247.  
  1248.  
  1249.  
  1250. Bool glXQueryVersion( Display *dpy, int *maj, int *min )
  1251. {
  1252.    /* Return GLX version, not Mesa version */
  1253.    *maj = 1;
  1254.    *min = 1;
  1255.    return True;
  1256. }
  1257.  
  1258.  
  1259.  
  1260. /*
  1261.  * Query the GLX attributes of the given XVisualInfo.
  1262.  */
  1263. int glXGetConfig( Display *dpy, XVisualInfo *visinfo,
  1264.           int attrib, int *value )
  1265. {
  1266.    int visclass;
  1267.    struct glx_visual *glvis;
  1268.  
  1269.    glvis = find_glx_visual( dpy, visinfo );
  1270.    if (!glvis) {
  1271.       /* this visual wasn't obtained with glXChooseVisual */
  1272.       int vislevel;
  1273.       if (is_overlay_visual( dpy, visinfo, &vislevel )) {
  1274.          /* Configure this visual as a CI, single-buffered overlay */
  1275.          glvis = save_glx_visual( dpy, visinfo,
  1276.                                   GL_FALSE,  /* rgb */
  1277.                                   GL_FALSE,  /* alpha */
  1278.                                   GL_FALSE,  /* double */
  1279.                                   0,         /* depth bits */
  1280.                                   0,         /* stencil bits */
  1281.                                   0,         /* accum bits */
  1282.                                   vislevel   /* level */
  1283.                                 );
  1284.       }
  1285.       else if (is_usable_visual( visinfo )) {
  1286.      /* Return "optimistic" values */
  1287.          glvis = save_glx_visual( dpy, visinfo,
  1288.                                   GL_TRUE,   /* rgb */
  1289.                                   GL_FALSE,  /* alpha */
  1290.                                   GL_TRUE,   /* double */
  1291.                                   8*sizeof(GLdepth),
  1292.                                   8*sizeof(GLstencil),
  1293.                                   8*sizeof(GLaccum),
  1294.                                   0          /* level */
  1295.                                 );
  1296.       }
  1297.       else {
  1298.      /* this visual can't be used for GL rendering */
  1299.      if (attrib==GLX_USE_GL) {
  1300.         *value = (int) False;
  1301.         return 0;
  1302.      }
  1303.      else {
  1304.         /*fprintf( stderr, "Mesa: Error in glXGetConfig: bad visual\n");*/
  1305.         return GLX_BAD_VISUAL;
  1306.      }
  1307.       }
  1308.    }
  1309.  
  1310.    /* Get the visual class */
  1311.    visclass = visinfo->CLASS;
  1312.  
  1313.    switch(attrib) {
  1314.       case GLX_USE_GL:
  1315.          *value = (int) True;
  1316.      return 0;
  1317.       case GLX_BUFFER_SIZE:
  1318.      *value = visinfo->depth;
  1319.      return 0;
  1320.       case GLX_LEVEL:
  1321.      *value = glvis->level;
  1322.      return 0;
  1323.       case GLX_RGBA:
  1324.      if (glvis->rgb_flag) {
  1325.         *value = True;
  1326.      }
  1327.      else {
  1328.         *value = False;
  1329.      }
  1330.      return 0;
  1331.       case GLX_DOUBLEBUFFER:
  1332.      *value = (int) glvis->double_flag;
  1333.      return 0;
  1334.       case GLX_STEREO:
  1335.      *value = (int) False;
  1336.      return 0;
  1337.       case GLX_AUX_BUFFERS:
  1338.      *value = (int) False;
  1339.      return 0;
  1340.       case GLX_RED_SIZE:
  1341.          if (visclass==DirectColor || visclass==TrueColor) {
  1342.             *value = bitcount( visinfo->visual->red_mask );
  1343.          }
  1344.          else {
  1345.             /* a crude approximation */
  1346.             *value = visinfo->depth;
  1347.          }
  1348.      return 0;
  1349.       case GLX_GREEN_SIZE:
  1350.          if (visclass==DirectColor || visclass==TrueColor) {
  1351.             *value = bitcount( visinfo->visual->green_mask );
  1352.          }
  1353.          else {
  1354.             *value = visinfo->depth;
  1355.          }
  1356.      return 0;
  1357.       case GLX_BLUE_SIZE:
  1358.          if (visclass==DirectColor || visclass==TrueColor) {
  1359.             *value = bitcount( visinfo->visual->blue_mask );
  1360.          }
  1361.          else {
  1362.             *value = visinfo->depth;
  1363.          }
  1364.      return 0;
  1365.       case GLX_ALPHA_SIZE:
  1366.          if (glvis->alpha_flag) {
  1367.             *value = 8;
  1368.          }
  1369.          else {
  1370.             *value = 0;
  1371.          }
  1372.      return 0;
  1373.       case GLX_DEPTH_SIZE:
  1374.          *value = glvis->depth_size;
  1375.      return 0;
  1376.       case GLX_STENCIL_SIZE:
  1377.      *value = glvis->stencil_size;
  1378.      return 0;
  1379.       case GLX_ACCUM_RED_SIZE:
  1380.       case GLX_ACCUM_GREEN_SIZE:
  1381.       case GLX_ACCUM_BLUE_SIZE:
  1382.       case GLX_ACCUM_ALPHA_SIZE:
  1383.      *value = glvis->accum_size;
  1384.      return 0;
  1385.  
  1386.       /*
  1387.        * GLX_EXT_visual_info extension
  1388.        */
  1389.       case GLX_X_VISUAL_TYPE_EXT:
  1390.          switch (glvis->visinfo->CLASS) {
  1391.             case StaticGray:   *value = GLX_STATIC_GRAY_EXT;   return 0;
  1392.             case GrayScale:    *value = GLX_GRAY_SCALE_EXT;    return 0;
  1393.             case StaticColor:  *value = GLX_STATIC_GRAY_EXT;   return 0;
  1394.             case PseudoColor:  *value = GLX_PSEUDO_COLOR_EXT;  return 0;
  1395.             case TrueColor:    *value = GLX_TRUE_COLOR_EXT;    return 0;
  1396.             case DirectColor:  *value = GLX_DIRECT_COLOR_EXT;  return 0;
  1397.          }
  1398.          return 0;
  1399.       case GLX_TRANSPARENT_TYPE_EXT:
  1400.          if (glvis->level==0) {
  1401.             /* normal planes */
  1402.             *value = GLX_NONE_EXT;
  1403.          }
  1404.          else if (glvis->level>0) {
  1405.             /* overlay */
  1406.             if (glvis->rgb_flag) {
  1407.                *value = GLX_TRANSPARENT_RGB_EXT;
  1408.             }
  1409.             else {
  1410.                *value = GLX_TRANSPARENT_INDEX_EXT;
  1411.             }
  1412.          }
  1413.          else if (glvis->level<0) {
  1414.             /* underlay */
  1415.             *value = GLX_NONE_EXT;
  1416.          }
  1417.          return 0;
  1418.       case GLX_TRANSPARENT_INDEX_VALUE_EXT:
  1419.          {
  1420.             int pixel = transparent_pixel( glvis );
  1421.             if (pixel>=0) {
  1422.                *value = pixel;
  1423.             }
  1424.             /* else undefined */
  1425.             return 0;
  1426.          }
  1427.          break;
  1428.       case GLX_TRANSPARENT_RED_VALUE_EXT:
  1429.          /* undefined */
  1430.          return 0;
  1431.       case GLX_TRANSPARENT_GREEN_VALUE_EXT:
  1432.          /* undefined */
  1433.          return 0;
  1434.       case GLX_TRANSPARENT_BLUE_VALUE_EXT:
  1435.          /* undefined */
  1436.          return 0;
  1437.       case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
  1438.          /* undefined */
  1439.          return 0;
  1440.  
  1441.       /*
  1442.        * Extensions
  1443.        */
  1444.       default:
  1445.      return GLX_BAD_ATTRIBUTE;
  1446.    }
  1447. }
  1448.  
  1449.  
  1450.  
  1451. GLXContext glXGetCurrentContext( void )
  1452. {
  1453.    return (GLXContext) XMesaGetCurrentContext();
  1454. }
  1455.  
  1456.  
  1457.  
  1458. GLXDrawable glXGetCurrentDrawable( void )
  1459. {
  1460.    XMesaContext ctx;
  1461.  
  1462.    ctx = XMesaGetCurrentContext();
  1463.    return ctx->frontbuffer;
  1464. }
  1465.  
  1466.  
  1467. void glXWaitGL( void )
  1468. {
  1469.    (*DD.flush)();
  1470. }
  1471.  
  1472.  
  1473.  
  1474. void glXWaitX( void )
  1475. {
  1476.    (*DD.flush)();
  1477. }
  1478.  
  1479.  
  1480.  
  1481. #define EXTENSIONS "GLX_MESA_pixmap_colormap GLX_EXT_visual_info"
  1482.  
  1483.  
  1484. /* GLX 1.1 and later */
  1485. const char *glXQueryExtensionsString( Display *dpy, int screen )
  1486. {
  1487.    static char *extensions = EXTENSIONS;
  1488.    return extensions;
  1489. }
  1490.  
  1491.  
  1492.  
  1493. /* GLX 1.1 and later */
  1494. const char *glXQueryServerString( Display *dpy, int screen, int name )
  1495. {
  1496.    static char *extensions = EXTENSIONS;
  1497.    static char *vendor = "Brian Paul";
  1498.    static char *version = "1.1 Mesa 1.2.8";
  1499.  
  1500.    switch (name) {
  1501.       case GLX_EXTENSIONS:
  1502.          return extensions;
  1503.       case GLX_VENDOR:
  1504.      return vendor;
  1505.       case GLX_VERSION:
  1506.      return version;
  1507.       default:
  1508.          return NULL;
  1509.    }
  1510. }
  1511.  
  1512.  
  1513.  
  1514. /* GLX 1.1 and later */
  1515. const char *glXGetClientString( Display *dpy, int name )
  1516. {
  1517.    static char *extensions = EXTENSIONS;
  1518.    static char *vendor = "Brian Paul";
  1519.    static char *version = "1.1 Mesa 1.2.8";
  1520.  
  1521.    switch (name) {
  1522.       case GLX_EXTENSIONS:
  1523.          return extensions;
  1524.       case GLX_VENDOR:
  1525.      return vendor;
  1526.       case GLX_VERSION:
  1527.      return version;
  1528.       default:
  1529.          return NULL;
  1530.    }
  1531. }
  1532.