glx_api.c revision 275d0e7e9282bfc8befe6d1427610a26c27e97d2
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Mesa 3-D graphics library
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Version:  7.6
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Permission is hereby granted, free of charge, to any person obtaining a
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * copy of this software and associated documentation files (the "Software"),
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to deal in the Software without restriction, including without limitation
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and/or sell copies of the Software, and to permit persons to whom the
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Software is furnished to do so, subject to the following conditions:
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The above copyright notice and this permission notice shall be included
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in all copies or substantial portions of the Software.
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * "Fake" GLX API implemented in terms of the XMesa*() functions.
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * XXX rename this file to glx_api.c
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define GLX_GLXEXT_PROTOTYPES
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "GL/glx.h"
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "xm_api.h"
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "context.h"
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h"
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "macros.h"
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "imports.h"
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "version.h"
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "state_tracker/st_context.h"
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "state_tracker/st_public.h"
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* This indicates the client-side GLX API and GLX encoder version. */
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CLIENT_MAJOR_VERSION 1
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CLIENT_MINOR_VERSION 4  /* but don't have 1.3's pbuffers, etc yet */
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* This indicates the server-side GLX decoder version.
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * GLX 1.4 indicates OpenGL 1.3 support
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SERVER_MAJOR_VERSION 1
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SERVER_MINOR_VERSION 4
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* This is appended onto the glXGetClient/ServerString version strings. */
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Who implemented this GLX? */
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define VENDOR "Brian Paul"
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EXTENSIONS \
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_MESA_copy_sub_buffer " \
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_MESA_pixmap_colormap " \
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_MESA_release_buffers " \
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_ARB_get_proc_address " \
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_EXT_texture_from_pixmap " \
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_EXT_visual_info " \
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_EXT_visual_rating " \
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   /*"GLX_SGI_video_sync "*/ \
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_SGIX_fbconfig " \
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   "GLX_SGIX_pbuffer "
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define DEFAULT_DIRECT GL_TRUE
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
78c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Minimal __GLXContextRec that mimics a "real" GLX context.
81c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt */
82c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidttypedef struct __GLXcontextRec
831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   Display *currentDpy;
85c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt   GLboolean isDirect;
861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   GLXDrawable currentDrawable;
87c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt   GLXDrawable currentReadable;
881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   XID xid;
89c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt} __GLXcontext;
90c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/**
931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Our fake GLX context will contain a "real" GLX context and an XMesa context.
94c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt *
95c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context,
96c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt * and vice versa.
971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *
98c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt * XXX merge this struct with the one above.
991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */
1001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct fake_glx_context
1011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
1021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   __GLXcontext glxContext;   /* this MUST be first! */
1031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   XMesaContext xmesaContext;
1041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt};
1051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic pipe_tsd ContextTSD;
1091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/** Set current context for calling thread */
1111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void
112c55524ad84d13014e8019491c2b17e5dcf13545aDmitry ShmidtSetCurrentContext(GLXContext c)
113c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt{
114c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt   pipe_tsd_set(&ContextTSD, c);
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** Get current context for calling thread */
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic GLXContext
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtGetCurrentContext(void)
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   return pipe_tsd_get(&ContextTSD);
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**********************************************************************/
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/***                     Debug helper code                          ***/
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**********************************************************************/
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern void _kw_ungrab_all( Display *dpy );
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid _kw_ungrab_all( Display *dpy )
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   XUngrabPointer( dpy, CurrentTime );
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   XUngrabKeyboard( dpy, CurrentTime );
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**********************************************************************/
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/***                       GLX Visual Code                          ***/
1411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/**********************************************************************/
1421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define DONT_CARE -1
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic XMesaVisual *VisualTable = NULL;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int NumVisuals = 0;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Macro to handle c_class vs class field name in XVisualInfo struct */
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(__cplusplus) || defined(c_plusplus)
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CLASS c_class
1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#else
1551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define CLASS class
1561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Test if the given XVisualInfo is usable for Mesa rendering.
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic GLboolean
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtis_usable_visual( XVisualInfo *vinfo )
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   switch (vinfo->CLASS) {
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case StaticGray:
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case GrayScale:
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /* Any StaticGray/GrayScale visual works in RGB or CI mode */
1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         return GL_TRUE;
1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      case StaticColor:
1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      case PseudoColor:
1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 /* Any StaticColor/PseudoColor visual of at least 4 bits */
1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 if (vinfo->depth>=4) {
1751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    return GL_TRUE;
1761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 }
1771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 else {
1781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    return GL_FALSE;
1791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 }
1801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      case TrueColor:
1811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      case DirectColor:
1821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 /* Any depth of TrueColor or DirectColor works in RGB mode */
1831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 return GL_TRUE;
1841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      default:
1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 /* This should never happen */
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 return GL_FALSE;
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration in our list of GLX visuals.
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic XMesaVisual
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsave_glx_visual( Display *dpy, XVisualInfo *vinfo,
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 GLboolean stereoFlag,
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 GLint depth_size, GLint stencil_size,
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 GLint accumRedSize, GLint accumGreenSize,
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 GLint accumBlueSize, GLint accumAlphaSize,
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 GLint level, GLint numAuxBuffers )
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLboolean ximageFlag = GL_TRUE;
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   XMesaVisual xmvis;
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint i;
2071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   GLboolean comparePointers;
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (dbFlag) {
2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      /* Check if the MESA_BACK_BUFFER env var is set */
2111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      char *backbuffer = _mesa_getenv("MESA_BACK_BUFFER");
2121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      if (backbuffer) {
2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         if (backbuffer[0]=='p' || backbuffer[0]=='P') {
2141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt            ximageFlag = GL_FALSE;
2151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         }
2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
2171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt            ximageFlag = GL_TRUE;
2181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         }
2191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         else {
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage.");
2211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         }
2221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      }
2231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   }
2241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (stereoFlag) {
2261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      /* stereo not supported */
2271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      return NULL;
2281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   }
2291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (stencil_size > 0 && depth_size > 0)
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      depth_size = 24;
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   /* Comparing IDs uses less memory but sometimes fails. */
2341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   /* XXX revisit this after 3.0 is finished. */
2351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   if (_mesa_getenv("MESA_GLX_VISUAL_HACK"))
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      comparePointers = GL_TRUE;
2371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   else
2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      comparePointers = GL_FALSE;
2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   /* Force the visual to have an alpha channel */
2411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA"))
2421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      alphaFlag = GL_TRUE;
2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   /* First check if a matching visual is already in the list */
2451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   for (i=0; i<NumVisuals; i++) {
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      XMesaVisual v = VisualTable[i];
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (v->display == dpy
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && v->mesa_visual.level == level
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && v->mesa_visual.numAuxBuffers == numAuxBuffers
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && v->ximage_flag == ximageFlag
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && v->mesa_visual.rgbMode == rgbFlag
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && v->mesa_visual.doubleBufferMode == dbFlag
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && v->mesa_visual.stereoMode == stereoFlag
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && (v->mesa_visual.alphaBits > 0) == alphaFlag
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && (v->mesa_visual.depthBits >= depth_size || depth_size == 0)
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0)
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0)
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0)
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0)
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) {
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /* now either compare XVisualInfo pointers or visual IDs */
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         if ((!comparePointers && v->visinfo->visualid == vinfo->visualid)
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt             || (comparePointers && v->vishandle == vinfo)) {
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return v;
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         }
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   /* Create a new visual and add it to the list. */
2701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              stereoFlag, ximageFlag,
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              depth_size, stencil_size,
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              accumRedSize, accumBlueSize,
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              accumBlueSize, accumAlphaSize, 0, level,
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              GLX_NONE_EXT );
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (xmvis) {
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* Save a copy of the pointer now so we can find this visual again
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt       * if we need to search for it in find_glx_visual().
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt       */
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      xmvis->vishandle = vinfo;
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* Allocate more space for additional visual */
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable,
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                   sizeof(XMesaVisual) * NumVisuals,
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                   sizeof(XMesaVisual) * (NumVisuals + 1));
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* add xmvis to the list */
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      VisualTable[NumVisuals] = xmvis;
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      NumVisuals++;
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* XXX minor hack, because XMesaCreateVisual doesn't support an
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt       * aux buffers parameter.
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt       */
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      xmvis->mesa_visual.numAuxBuffers = numAuxBuffers;
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   return xmvis;
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Return the default number of bits for the Z buffer.
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If defined, use the MESA_GLX_DEPTH_BITS env var value.
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant.
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * XXX probably do the same thing for stencil, accum, etc.
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic GLint
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdefault_depth_bits(void)
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int zBits;
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS");
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (zEnv)
31075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen      zBits = _mesa_atoi(zEnv);
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   else
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      zBits = DEFAULT_SOFTWARE_DEPTH_BITS;
31375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen   return zBits;
31475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
31575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
31675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic GLint
31775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinendefault_alpha_bits(void)
31875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
31975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen   int aBits;
32075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen   const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS");
32175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen   if (aEnv)
32275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen      aBits = _mesa_atoi(aEnv);
32375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen   else
32475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen      aBits = 0;
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   return aBits;
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic GLint
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdefault_accum_bits(void)
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   return 16;
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Create a GLX visual from a regular XVisualInfo.
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is called when Fake GLX is given an XVisualInfo which wasn't
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * returned by glXChooseVisual.  Since this is the first time we're
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * considering this visual we'll take a guess at reasonable values
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for depth buffer size, stencil size, accum size, etc.
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is the best we can do with a client-side emulation of GLX.
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic XMesaVisual
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtcreate_glx_visual( Display *dpy, XVisualInfo *visinfo )
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint zBits = default_depth_bits();
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint accBits = default_accum_bits();
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLboolean alphaFlag = default_alpha_bits() > 0;
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (is_usable_visual( visinfo )) {
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* Configure this visual as RGB, double-buffered, depth-buffered. */
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* This is surely wrong for some people's needs but what else */
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* can be done?  They should use glXChooseVisual(). */
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return save_glx_visual( dpy, visinfo,
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              GL_TRUE,   /* rgb */
3571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt                              alphaFlag, /* alpha */
3581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt                              GL_TRUE,   /* double */
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              GL_FALSE,  /* stereo */
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              zBits,
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              STENCIL_BITS,
3621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt                              accBits, /* r */
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              accBits, /* g */
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              accBits, /* b */
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              accBits, /* a */
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              0,         /* level */
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                              0          /* numAux */
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         );
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   else {
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n");
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return NULL;
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Find the GLX visual associated with an XVisualInfo.
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic XMesaVisual
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfind_glx_visual( Display *dpy, XVisualInfo *vinfo )
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int i;
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   /* try to match visual id */
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   for (i=0;i<NumVisuals;i++) {
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (VisualTable[i]->display==dpy
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         return VisualTable[i];
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   /* if that fails, try to match pointers */
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   for (i=0;i<NumVisuals;i++) {
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         return VisualTable[i];
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   return NULL;
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Try to get an X visual which matches the given arguments.
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic XVisualInfo *
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtget_visual( Display *dpy, int scr, unsigned int depth, int xclass )
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   XVisualInfo temp, *vis;
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   long mask;
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int n;
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   unsigned int default_depth;
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int default_class;
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   temp.screen = scr;
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   temp.depth = depth;
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   temp.CLASS = xclass;
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   default_depth = DefaultDepth(dpy,scr);
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   default_class = DefaultVisual(dpy,scr)->CLASS;
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (depth==default_depth && xclass==default_class) {
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* try to get root window's visual */
4271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      temp.visualid = DefaultVisual(dpy,scr)->visualid;
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      mask |= VisualIDMask;
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   vis = XGetVisualInfo( dpy, mask, &temp, &n );
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    * An SGI Infinite Reality system, for example, can have 30bpp pixels:
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    * 10 bits per color channel.  Mesa's limited to a max of 8 bits/channel.
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    */
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (_mesa_bitcount((GLuint) vis->red_mask  ) <= 8 &&
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          _mesa_bitcount((GLuint) vis->green_mask) <= 8 &&
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) {
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         return vis;
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      else {
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         XFree((void *) vis);
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         return NULL;
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   return vis;
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Retrieve the value of the given environment variable and find
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the X visual which matches it.
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Input:  dpy - the display
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *         screen - the screen number
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *         varname - the name of the environment variable
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Return:  an XVisualInfo pointer to NULL if error.
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic XVisualInfo *
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtget_env_visual(Display *dpy, int scr, const char *varname)
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   char value[100], type[100];
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int depth, xclass = -1;
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   XVisualInfo *vis;
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   if (!_mesa_getenv( varname )) {
4691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      return NULL;
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   _mesa_strncpy( value, _mesa_getenv(varname), 100 );
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   value[99] = 0;
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   sscanf( value, "%s %d", type, &depth );
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   if (_mesa_strcmp(type,"TrueColor")==0)          xclass = TrueColor;
4781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   else if (_mesa_strcmp(type,"DirectColor")==0)   xclass = DirectColor;
4791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   else if (_mesa_strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
4801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   else if (_mesa_strcmp(type,"StaticColor")==0)   xclass = StaticColor;
4811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   else if (_mesa_strcmp(type,"GrayScale")==0)     xclass = GrayScale;
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   else if (_mesa_strcmp(type,"StaticGray")==0)    xclass = StaticGray;
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (xclass>-1 && depth>0) {
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      vis = get_visual( dpy, scr, depth, xclass );
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (vis) {
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 return vis;
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.",
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 type, depth);
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   return NULL;
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Select an X visual which satisfies the RGBA flag and minimum depth.
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Input:  dpy,
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *         screen - X display and screen number
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *         min_depth - minimum visual depth
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *         preferred_class - preferred GLX visual class or DONT_CARE
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Return:  pointer to an XVisualInfo or NULL.
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic XVisualInfo *
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchoose_x_visual( Display *dpy, int screen, int min_depth,
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 int preferred_class )
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   XVisualInfo *vis;
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int xclass, visclass = 0;
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int depth;
514497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   /* First see if the MESA_RGB_VISUAL env var is defined */
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (vis) {
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return vis;
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   /* Otherwise, search for a suitable visual */
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (preferred_class==DONT_CARE) {
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      for (xclass=0;xclass<6;xclass++) {
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         switch (xclass) {
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case 0:  visclass = TrueColor;    break;
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case 1:  visclass = DirectColor;  break;
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case 2:  visclass = PseudoColor;  break;
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case 3:  visclass = StaticColor;  break;
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case 4:  visclass = GrayScale;    break;
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case 5:  visclass = StaticGray;   break;
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         }
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         if (min_depth==0) {
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            /* start with shallowest */
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            for (depth=0;depth<=32;depth++) {
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               if (visclass==TrueColor && depth==8) {
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  /* Special case:  try to get 8-bit PseudoColor before */
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  /* 8-bit TrueColor */
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  vis = get_visual( dpy, screen, 8, PseudoColor );
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  if (vis) {
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                     return vis;
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  }
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               }
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               vis = get_visual( dpy, screen, depth, visclass );
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               if (vis) {
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  return vis;
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               }
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         }
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         else {
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            /* start with deepest */
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            for (depth=32;depth>=min_depth;depth--) {
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               if (visclass==TrueColor && depth==8) {
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  /* Special case:  try to get 8-bit PseudoColor before */
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  /* 8-bit TrueColor */
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  vis = get_visual( dpy, screen, 8, PseudoColor );
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  if (vis) {
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                     return vis;
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  }
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               }
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               vis = get_visual( dpy, screen, depth, visclass );
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               if (vis) {
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                  return vis;
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               }
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         }
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
566c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt   }
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   else {
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* search for a specific visual class */
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      switch (preferred_class) {
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      default:   return NULL;
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (min_depth==0) {
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /* start with shallowest */
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         for (depth=0;depth<=32;depth++) {
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            vis = get_visual( dpy, screen, depth, visclass );
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (vis) {
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return vis;
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         }
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      else {
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /* start with deepest */
5891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         for (depth=32;depth>=min_depth;depth--) {
5901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt            vis = get_visual( dpy, screen, depth, visclass );
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (vis) {
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return vis;
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
5941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         }
5951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      }
5961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   }
5971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
5981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   /* didn't find a visual */
5991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   return NULL;
6001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
6011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/**********************************************************************/
6061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/***             Display-related functions                          ***/
6071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/**********************************************************************/
6081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/**
6111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Free all XMesaVisuals which are associated with the given display.
6121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */
6131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdestroy_visuals_on_display(Display *dpy)
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int i;
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   for (i = 0; i < NumVisuals; i++) {
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (VisualTable[i]->display == dpy) {
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /* remove this visual */
6201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         int j;
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         free(VisualTable[i]);
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         for (j = i; j < NumVisuals - 1; j++)
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            VisualTable[j] = VisualTable[j + 1];
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         NumVisuals--;
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Called from XCloseDisplay() to let us free our display-related data.
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclose_display_callback(Display *dpy, XExtCodes *codes)
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   destroy_visuals_on_display(dpy);
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   xmesa_destroy_buffers_on_display(dpy);
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   return 0;
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Look for the named extension on given display and return a pointer
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the _XExtension data, or NULL if extension not found.
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic _XExtension *
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtlookup_extension(Display *dpy, const char *extName)
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   _XExtension *ext;
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   for (ext = dpy->ext_procs; ext; ext = ext->next) {
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (ext->name && strcmp(ext->name, extName) == 0) {
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         return ext;
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   return NULL;
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Whenever we're given a new Display pointer, call this function to
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * register our close_display_callback function.
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtregister_with_display(Display *dpy)
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   const char *extName = "MesaGLX";
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   _XExtension *ext;
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   ext = lookup_extension(dpy, extName);
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (!ext) {
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      XExtCodes *c = XAddExtension(dpy);
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      ext = dpy->ext_procs;  /* new extension is at head of list */
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      assert(c->extension == ext->codes.extension);
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      ext->name = _mesa_strdup(extName);
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      ext->close_display = close_display_callback;
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**********************************************************************/
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/***                  Begin Fake GLX API Functions                  ***/
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**********************************************************************/
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Helper used by glXChooseVisual and glXChooseFBConfig.
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the later.
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * In either case, the attribute list is terminated with the value 'None'.
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic XMesaVisual
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchoose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   const GLboolean rgbModeDefault = fbConfig;
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   const int *parselist;
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   XVisualInfo *vis;
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int min_ci = 0;
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int min_red=0, min_green=0, min_blue=0;
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLboolean rgb_flag = rgbModeDefault;
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLboolean alpha_flag = GL_FALSE;
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLboolean double_flag = GL_FALSE;
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLboolean stereo_flag = GL_FALSE;
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint depth_size = 0;
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint stencil_size = 0;
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint accumRedSize = 0;
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint accumGreenSize = 0;
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint accumBlueSize = 0;
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint accumAlphaSize = 0;
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int level = 0;
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int visual_type = DONT_CARE;
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int trans_type = DONT_CARE;
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int trans_value = DONT_CARE;
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   GLint caveat = DONT_CARE;
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   XMesaVisual xmvis = NULL;
7151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt   int desiredVisualID = -1;
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   int numAux = 0;
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   parselist = list;
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   while (*parselist) {
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      switch (*parselist) {
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_USE_GL:
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (fbConfig) {
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               /* invalid token */
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL;
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            else {
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               /* skip */
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               parselist++;
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_BUFFER_SIZE:
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    min_ci = *parselist++;
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_LEVEL:
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            level = *parselist++;
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_RGBA:
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (fbConfig) {
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               /* invalid token */
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL;
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            else {
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               rgb_flag = GL_TRUE;
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               parselist++;
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_DOUBLEBUFFER:
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (fbConfig) {
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               double_flag = *parselist++;
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            else {
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               double_flag = GL_TRUE;
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_STEREO:
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (fbConfig) {
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               stereo_flag = *parselist++;
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            else {
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               stereo_flag = GL_TRUE;
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_AUX_BUFFERS:
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            numAux = *parselist++;
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (numAux > MAX_AUX_BUFFERS)
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL;
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_RED_SIZE:
7761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    parselist++;
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    min_red = *parselist++;
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_GREEN_SIZE:
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    min_green = *parselist++;
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_BLUE_SIZE:
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    min_blue = *parselist++;
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_ALPHA_SIZE:
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            {
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               GLint size = *parselist++;
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               alpha_flag = size ? GL_TRUE : GL_FALSE;
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_DEPTH_SIZE:
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    depth_size = *parselist++;
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_STENCIL_SIZE:
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    stencil_size = *parselist++;
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_ACCUM_RED_SIZE:
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            {
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               GLint size = *parselist++;
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               accumRedSize = MAX2( accumRedSize, size );
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_ACCUM_GREEN_SIZE:
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            {
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               GLint size = *parselist++;
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               accumGreenSize = MAX2( accumGreenSize, size );
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_ACCUM_BLUE_SIZE:
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            {
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               GLint size = *parselist++;
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               accumBlueSize = MAX2( accumBlueSize, size );
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case GLX_ACCUM_ALPHA_SIZE:
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            {
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               GLint size = *parselist++;
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               accumAlphaSize = MAX2( accumAlphaSize, size );
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /*
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          * GLX_EXT_visual_info extension
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          */
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_X_VISUAL_TYPE_EXT:
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            visual_type = *parselist++;
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_TRANSPARENT_TYPE_EXT:
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            trans_type = *parselist++;
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_TRANSPARENT_INDEX_VALUE_EXT:
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            trans_value = *parselist++;
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_TRANSPARENT_RED_VALUE_EXT:
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_TRANSPARENT_GREEN_VALUE_EXT:
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_TRANSPARENT_BLUE_VALUE_EXT:
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    /* ignore */
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    parselist++;
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /*
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          * GLX_EXT_visual_info extension
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          */
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_VISUAL_CAVEAT_EXT:
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            caveat = *parselist++; /* ignored for now */
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /*
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          * GLX_ARB_multisample
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          */
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_SAMPLE_BUFFERS_ARB:
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            /* ms not supported */
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return NULL;
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_SAMPLES_ARB:
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            /* ms not supported */
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return NULL;
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /*
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          * FBConfig attribs.
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          */
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_RENDER_TYPE:
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (!fbConfig)
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL;
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (*parselist == GLX_RGBA_BIT) {
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               rgb_flag = GL_TRUE;
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            else if (*parselist == GLX_COLOR_INDEX_BIT) {
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               rgb_flag = GL_FALSE;
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            else if (*parselist == 0) {
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               rgb_flag = GL_TRUE;
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_DRAWABLE_TYPE:
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (!fbConfig)
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL;
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) {
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL; /* bad bit */
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_FBCONFIG_ID:
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (!fbConfig)
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL;
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            desiredVisualID = *parselist++;
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_X_RENDERABLE:
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (!fbConfig)
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL;
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist += 2;
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            /* ignore */
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef GLX_EXT_texture_from_pixmap
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_BIND_TO_TEXTURE_RGB_EXT:
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++; /*skip*/
9161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt            break;
9171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         case GLX_BIND_TO_TEXTURE_RGBA_EXT:
9181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt            parselist++; /*skip*/
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++; /*skip*/
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++;
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT |
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                               GLX_TEXTURE_2D_BIT_EXT |
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                               GLX_TEXTURE_RECTANGLE_BIT_EXT)) {
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               /* invalid bit */
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               return NULL;
9301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt            }
9311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt            break;
9321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt         case GLX_Y_INVERTED_EXT:
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            parselist++; /*skip*/
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 case None:
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            /* end of list */
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    break;
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 default:
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    /* undefined attribute */
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()",
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                          *parselist);
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    return NULL;
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   (void) caveat;
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   /*
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    * Since we're only simulating the GLX extension this function will never
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    * find any real GL visuals.  Instead, all we can do is try to find an RGB
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    * or CI visual of appropriate depth.  Other requested attributes such as
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    * double buffering, depth buffer, etc. will be associated with the X
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    * visual and stored in the VisualTable[].
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    */
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   if (desiredVisualID != -1) {
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* try to get a specific visual, by visualID */
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      XVisualInfo temp;
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      int n;
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      temp.visualid = desiredVisualID;
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      temp.screen = screen;
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n);
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (vis) {
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /* give the visual some useful GLX attributes */
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         double_flag = GL_TRUE;
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         rgb_flag = GL_TRUE;
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         depth_size = default_depth_bits();
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         stencil_size = STENCIL_BITS;
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         /* XXX accum??? */
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   }
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   else if (level==0) {
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* normal color planes */
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      /* Get an RGB visual */
978      int min_rgb = min_red + min_green + min_blue;
979      if (min_rgb>1 && min_rgb<8) {
980         /* a special case to be sure we can get a monochrome visual */
981         min_rgb = 1;
982      }
983      vis = choose_x_visual( dpy, screen, min_rgb, visual_type );
984   }
985   else {
986      _mesa_warning(NULL, "overlay not supported");
987      return NULL;
988   }
989
990   if (vis) {
991      /* Note: we're not exactly obeying the glXChooseVisual rules here.
992       * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
993       * largest depth buffer size, which is 32bits/value.  Instead, we
994       * return 16 to maintain performance with earlier versions of Mesa.
995       */
996      if (stencil_size > 0)
997         depth_size = 24;  /* if Z and stencil, always use 24+8 format */
998      else if (depth_size > 24)
999         depth_size = 32;
1000      else if (depth_size > 16)
1001         depth_size = 24;
1002      else if (depth_size > 0) {
1003         depth_size = default_depth_bits();
1004      }
1005
1006      if (!alpha_flag) {
1007         alpha_flag = default_alpha_bits() > 0;
1008      }
1009
1010      /* we only support one size of stencil and accum buffers. */
1011      if (stencil_size > 0)
1012         stencil_size = STENCIL_BITS;
1013
1014      if (accumRedSize > 0 ||
1015          accumGreenSize > 0 ||
1016          accumBlueSize > 0 ||
1017          accumAlphaSize > 0) {
1018
1019         accumRedSize =
1020            accumGreenSize =
1021            accumBlueSize = default_accum_bits();
1022
1023         accumAlphaSize = alpha_flag ? accumRedSize : 0;
1024      }
1025
1026      xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
1027                               stereo_flag, depth_size, stencil_size,
1028                               accumRedSize, accumGreenSize,
1029                               accumBlueSize, accumAlphaSize, level, numAux );
1030   }
1031
1032   return xmvis;
1033}
1034
1035
1036XVisualInfo *
1037glXChooseVisual( Display *dpy, int screen, int *list )
1038{
1039   XMesaVisual xmvis;
1040
1041   /* register ourselves as an extension on this display */
1042   register_with_display(dpy);
1043
1044   xmvis = choose_visual(dpy, screen, list, GL_FALSE);
1045   if (xmvis) {
1046      /* create a new vishandle - the cached one may be stale */
1047      xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
1048      if (xmvis->vishandle) {
1049         _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
1050      }
1051      return xmvis->vishandle;
1052   }
1053   else
1054      return NULL;
1055}
1056
1057
1058GLXContext
1059glXCreateContext( Display *dpy, XVisualInfo *visinfo,
1060                  GLXContext share_list, Bool direct )
1061{
1062   XMesaVisual xmvis;
1063   struct fake_glx_context *glxCtx;
1064   struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
1065
1066   if (!dpy || !visinfo)
1067      return 0;
1068
1069   glxCtx = CALLOC_STRUCT(fake_glx_context);
1070   if (!glxCtx)
1071      return 0;
1072
1073   /* deallocate unused windows/buffers */
1074#if 0
1075   XMesaGarbageCollect();
1076#endif
1077
1078   xmvis = find_glx_visual( dpy, visinfo );
1079   if (!xmvis) {
1080      /* This visual wasn't found with glXChooseVisual() */
1081      xmvis = create_glx_visual( dpy, visinfo );
1082      if (!xmvis) {
1083         /* unusable visual */
1084         _mesa_free(glxCtx);
1085         return NULL;
1086      }
1087   }
1088
1089   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
1090                                   shareCtx ? shareCtx->xmesaContext : NULL);
1091   if (!glxCtx->xmesaContext) {
1092      _mesa_free(glxCtx);
1093      return NULL;
1094   }
1095
1096   glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
1097   glxCtx->glxContext.currentDpy = dpy;
1098   glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */
1099
1100   assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
1101
1102   return (GLXContext) glxCtx;
1103}
1104
1105
1106/* XXX these may have to be removed due to thread-safety issues. */
1107static GLXContext MakeCurrent_PrevContext = 0;
1108static GLXDrawable MakeCurrent_PrevDrawable = 0;
1109static GLXDrawable MakeCurrent_PrevReadable = 0;
1110static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
1111static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
1112
1113
1114/* GLX 1.3 and later */
1115Bool
1116glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
1117                       GLXDrawable read, GLXContext ctx )
1118{
1119   struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
1120   static boolean firsttime = 1, no_rast = 0;
1121
1122   if (firsttime) {
1123      no_rast = getenv("SP_NO_RAST") != NULL;
1124      firsttime = 0;
1125   }
1126
1127   if (ctx && draw && read) {
1128      XMesaBuffer drawBuffer, readBuffer;
1129      XMesaContext xmctx = glxCtx->xmesaContext;
1130
1131      /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
1132      if (ctx == MakeCurrent_PrevContext
1133          && draw == MakeCurrent_PrevDrawable) {
1134         drawBuffer = MakeCurrent_PrevDrawBuffer;
1135      }
1136      else {
1137         drawBuffer = XMesaFindBuffer( dpy, draw );
1138      }
1139      if (!drawBuffer) {
1140         /* drawable must be a new window! */
1141         drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
1142         if (!drawBuffer) {
1143            /* Out of memory, or context/drawable depth mismatch */
1144            return False;
1145         }
1146      }
1147
1148      /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
1149      if (ctx == MakeCurrent_PrevContext
1150          && read == MakeCurrent_PrevReadable) {
1151         readBuffer = MakeCurrent_PrevReadBuffer;
1152      }
1153      else {
1154         readBuffer = XMesaFindBuffer( dpy, read );
1155      }
1156      if (!readBuffer) {
1157         /* drawable must be a new window! */
1158         readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
1159         if (!readBuffer) {
1160            /* Out of memory, or context/drawable depth mismatch */
1161            return False;
1162         }
1163      }
1164
1165      if (no_rast &&
1166          MakeCurrent_PrevContext == ctx &&
1167          MakeCurrent_PrevDrawable == draw &&
1168          MakeCurrent_PrevReadable == read &&
1169          MakeCurrent_PrevDrawBuffer == drawBuffer &&
1170          MakeCurrent_PrevReadBuffer == readBuffer)
1171         return True;
1172
1173      MakeCurrent_PrevContext = ctx;
1174      MakeCurrent_PrevDrawable = draw;
1175      MakeCurrent_PrevReadable = read;
1176      MakeCurrent_PrevDrawBuffer = drawBuffer;
1177      MakeCurrent_PrevReadBuffer = readBuffer;
1178
1179      /* Now make current! */
1180      if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
1181         ((__GLXcontext *) ctx)->currentDpy = dpy;
1182         ((__GLXcontext *) ctx)->currentDrawable = draw;
1183         ((__GLXcontext *) ctx)->currentReadable = read;
1184         SetCurrentContext(ctx);
1185         return True;
1186      }
1187      else {
1188         return False;
1189      }
1190   }
1191   else if (!ctx && !draw && !read) {
1192      /* release current context w/out assigning new one. */
1193      XMesaMakeCurrent2( NULL, NULL, NULL );
1194      MakeCurrent_PrevContext = 0;
1195      MakeCurrent_PrevDrawable = 0;
1196      MakeCurrent_PrevReadable = 0;
1197      MakeCurrent_PrevDrawBuffer = 0;
1198      MakeCurrent_PrevReadBuffer = 0;
1199      SetCurrentContext(NULL);
1200      return True;
1201   }
1202   else {
1203      /* The args must either all be non-zero or all zero.
1204       * This is an error.
1205       */
1206      return False;
1207   }
1208}
1209
1210
1211Bool
1212glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
1213{
1214   return glXMakeContextCurrent( dpy, drawable, drawable, ctx );
1215}
1216
1217
1218GLXContext
1219glXGetCurrentContext(void)
1220{
1221   return GetCurrentContext();
1222}
1223
1224
1225Display *
1226glXGetCurrentDisplay(void)
1227{
1228   struct fake_glx_context *glxCtx =
1229      (struct fake_glx_context *) glXGetCurrentContext();
1230
1231   return glxCtx ? glxCtx->glxContext.currentDpy : NULL;
1232}
1233
1234
1235Display *
1236glXGetCurrentDisplayEXT(void)
1237{
1238   return glXGetCurrentDisplay();
1239}
1240
1241
1242GLXDrawable
1243glXGetCurrentDrawable(void)
1244{
1245   __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
1246   return gc ? gc->currentDrawable : 0;
1247}
1248
1249
1250GLXDrawable
1251glXGetCurrentReadDrawable(void)
1252{
1253   __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
1254   return gc ? gc->currentReadable : 0;
1255}
1256
1257
1258GLXDrawable
1259glXGetCurrentReadDrawableSGI(void)
1260{
1261   return glXGetCurrentReadDrawable();
1262}
1263
1264
1265GLXPixmap
1266glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
1267{
1268   XMesaVisual v;
1269   XMesaBuffer b;
1270
1271   v = find_glx_visual( dpy, visinfo );
1272   if (!v) {
1273      v = create_glx_visual( dpy, visinfo );
1274      if (!v) {
1275         /* unusable visual */
1276         return 0;
1277      }
1278   }
1279
1280   b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
1281   if (!b) {
1282      return 0;
1283   }
1284   return b->drawable;
1285}
1286
1287
1288/*** GLX_MESA_pixmap_colormap ***/
1289
1290GLXPixmap
1291glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
1292                        Pixmap pixmap, Colormap cmap )
1293{
1294   XMesaVisual v;
1295   XMesaBuffer b;
1296
1297   v = find_glx_visual( dpy, visinfo );
1298   if (!v) {
1299      v = create_glx_visual( dpy, visinfo );
1300      if (!v) {
1301         /* unusable visual */
1302         return 0;
1303      }
1304   }
1305
1306   b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
1307   if (!b) {
1308      return 0;
1309   }
1310   return b->drawable;
1311}
1312
1313
1314void
1315glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
1316{
1317   XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
1318   if (b) {
1319      XMesaDestroyBuffer(b);
1320   }
1321   else if (_mesa_getenv("MESA_DEBUG")) {
1322      _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
1323   }
1324}
1325
1326
1327void
1328glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
1329                unsigned long mask )
1330{
1331   struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src;
1332   struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst;
1333   XMesaContext xm_src = fakeSrc->xmesaContext;
1334   XMesaContext xm_dst = fakeDst->xmesaContext;
1335   (void) dpy;
1336   if (MakeCurrent_PrevContext == src) {
1337      _mesa_Flush();
1338   }
1339   st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask );
1340}
1341
1342
1343Bool
1344glXQueryExtension( Display *dpy, int *errorb, int *event )
1345{
1346   /* Mesa's GLX isn't really an X extension but we try to act like one. */
1347   (void) dpy;
1348   (void) errorb;
1349   (void) event;
1350   return True;
1351}
1352
1353
1354void
1355glXDestroyContext( Display *dpy, GLXContext ctx )
1356{
1357   struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
1358   (void) dpy;
1359   MakeCurrent_PrevContext = 0;
1360   MakeCurrent_PrevDrawable = 0;
1361   MakeCurrent_PrevReadable = 0;
1362   MakeCurrent_PrevDrawBuffer = 0;
1363   MakeCurrent_PrevReadBuffer = 0;
1364   XMesaDestroyContext( glxCtx->xmesaContext );
1365   XMesaGarbageCollect();
1366   _mesa_free(glxCtx);
1367}
1368
1369
1370Bool
1371glXIsDirect( Display *dpy, GLXContext ctx )
1372{
1373   struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
1374   (void) ctx;
1375   return glxCtx->glxContext.isDirect;
1376}
1377
1378
1379
1380void
1381glXSwapBuffers( Display *dpy, GLXDrawable drawable )
1382{
1383   XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1384   static boolean firsttime = 1, no_rast = 0;
1385
1386   if (firsttime) {
1387      no_rast = getenv("SP_NO_RAST") != NULL;
1388      firsttime = 0;
1389   }
1390
1391   if (no_rast)
1392      return;
1393
1394   if (buffer) {
1395      XMesaSwapBuffers(buffer);
1396   }
1397   else if (_mesa_getenv("MESA_DEBUG")) {
1398      _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n",
1399                    (int) drawable);
1400   }
1401}
1402
1403
1404
1405/*** GLX_MESA_copy_sub_buffer ***/
1406
1407void
1408glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
1409                           int x, int y, int width, int height )
1410{
1411   XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1412   if (buffer) {
1413      XMesaCopySubBuffer(buffer, x, y, width, height);
1414   }
1415   else if (_mesa_getenv("MESA_DEBUG")) {
1416      _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n");
1417   }
1418}
1419
1420
1421Bool
1422glXQueryVersion( Display *dpy, int *maj, int *min )
1423{
1424   (void) dpy;
1425   /* Return GLX version, not Mesa version */
1426   assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
1427   *maj = CLIENT_MAJOR_VERSION;
1428   *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
1429   return True;
1430}
1431
1432
1433/*
1434 * Query the GLX attributes of the given XVisualInfo.
1435 */
1436static int
1437get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
1438{
1439   ASSERT(xmvis);
1440   switch(attrib) {
1441      case GLX_USE_GL:
1442         if (fbconfig)
1443            return GLX_BAD_ATTRIBUTE;
1444         *value = (int) True;
1445	 return 0;
1446      case GLX_BUFFER_SIZE:
1447	 *value = xmvis->visinfo->depth;
1448	 return 0;
1449      case GLX_LEVEL:
1450	 *value = xmvis->mesa_visual.level;
1451	 return 0;
1452      case GLX_RGBA:
1453         if (fbconfig)
1454            return GLX_BAD_ATTRIBUTE;
1455	 if (xmvis->mesa_visual.rgbMode) {
1456	    *value = True;
1457	 }
1458	 else {
1459	    *value = False;
1460	 }
1461	 return 0;
1462      case GLX_DOUBLEBUFFER:
1463	 *value = (int) xmvis->mesa_visual.doubleBufferMode;
1464	 return 0;
1465      case GLX_STEREO:
1466	 *value = (int) xmvis->mesa_visual.stereoMode;
1467	 return 0;
1468      case GLX_AUX_BUFFERS:
1469	 *value = xmvis->mesa_visual.numAuxBuffers;
1470	 return 0;
1471      case GLX_RED_SIZE:
1472         *value = xmvis->mesa_visual.redBits;
1473	 return 0;
1474      case GLX_GREEN_SIZE:
1475         *value = xmvis->mesa_visual.greenBits;
1476	 return 0;
1477      case GLX_BLUE_SIZE:
1478         *value = xmvis->mesa_visual.blueBits;
1479	 return 0;
1480      case GLX_ALPHA_SIZE:
1481         *value = xmvis->mesa_visual.alphaBits;
1482	 return 0;
1483      case GLX_DEPTH_SIZE:
1484         *value = xmvis->mesa_visual.depthBits;
1485	 return 0;
1486      case GLX_STENCIL_SIZE:
1487	 *value = xmvis->mesa_visual.stencilBits;
1488	 return 0;
1489      case GLX_ACCUM_RED_SIZE:
1490	 *value = xmvis->mesa_visual.accumRedBits;
1491	 return 0;
1492      case GLX_ACCUM_GREEN_SIZE:
1493	 *value = xmvis->mesa_visual.accumGreenBits;
1494	 return 0;
1495      case GLX_ACCUM_BLUE_SIZE:
1496	 *value = xmvis->mesa_visual.accumBlueBits;
1497	 return 0;
1498      case GLX_ACCUM_ALPHA_SIZE:
1499         *value = xmvis->mesa_visual.accumAlphaBits;
1500	 return 0;
1501
1502      /*
1503       * GLX_EXT_visual_info extension
1504       */
1505      case GLX_X_VISUAL_TYPE_EXT:
1506         switch (xmvis->visinfo->CLASS) {
1507            case StaticGray:   *value = GLX_STATIC_GRAY_EXT;   return 0;
1508            case GrayScale:    *value = GLX_GRAY_SCALE_EXT;    return 0;
1509            case StaticColor:  *value = GLX_STATIC_GRAY_EXT;   return 0;
1510            case PseudoColor:  *value = GLX_PSEUDO_COLOR_EXT;  return 0;
1511            case TrueColor:    *value = GLX_TRUE_COLOR_EXT;    return 0;
1512            case DirectColor:  *value = GLX_DIRECT_COLOR_EXT;  return 0;
1513         }
1514         return 0;
1515      case GLX_TRANSPARENT_TYPE_EXT:
1516         /* normal planes */
1517         *value = GLX_NONE_EXT;
1518         return 0;
1519      case GLX_TRANSPARENT_INDEX_VALUE_EXT:
1520         /* undefined */
1521         return 0;
1522      case GLX_TRANSPARENT_RED_VALUE_EXT:
1523         /* undefined */
1524         return 0;
1525      case GLX_TRANSPARENT_GREEN_VALUE_EXT:
1526         /* undefined */
1527         return 0;
1528      case GLX_TRANSPARENT_BLUE_VALUE_EXT:
1529         /* undefined */
1530         return 0;
1531      case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
1532         /* undefined */
1533         return 0;
1534
1535      /*
1536       * GLX_EXT_visual_info extension
1537       */
1538      case GLX_VISUAL_CAVEAT_EXT:
1539         /* test for zero, just in case */
1540         if (xmvis->mesa_visual.visualRating > 0)
1541            *value = xmvis->mesa_visual.visualRating;
1542         else
1543            *value = GLX_NONE_EXT;
1544         return 0;
1545
1546      /*
1547       * GLX_ARB_multisample
1548       */
1549      case GLX_SAMPLE_BUFFERS_ARB:
1550         *value = 0;
1551         return 0;
1552      case GLX_SAMPLES_ARB:
1553         *value = 0;
1554         return 0;
1555
1556      /*
1557       * For FBConfigs:
1558       */
1559      case GLX_SCREEN_EXT:
1560         if (!fbconfig)
1561            return GLX_BAD_ATTRIBUTE;
1562         *value = xmvis->visinfo->screen;
1563         break;
1564      case GLX_DRAWABLE_TYPE: /*SGIX too */
1565         if (!fbconfig)
1566            return GLX_BAD_ATTRIBUTE;
1567         *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
1568         break;
1569      case GLX_RENDER_TYPE_SGIX:
1570         if (!fbconfig)
1571            return GLX_BAD_ATTRIBUTE;
1572         if (xmvis->mesa_visual.rgbMode)
1573            *value = GLX_RGBA_BIT;
1574         else
1575            *value = GLX_COLOR_INDEX_BIT;
1576         break;
1577      case GLX_X_RENDERABLE_SGIX:
1578         if (!fbconfig)
1579            return GLX_BAD_ATTRIBUTE;
1580         *value = True; /* XXX really? */
1581         break;
1582      case GLX_FBCONFIG_ID_SGIX:
1583         if (!fbconfig)
1584            return GLX_BAD_ATTRIBUTE;
1585         *value = xmvis->visinfo->visualid;
1586         break;
1587      case GLX_MAX_PBUFFER_WIDTH:
1588         if (!fbconfig)
1589            return GLX_BAD_ATTRIBUTE;
1590         /* XXX or MAX_WIDTH? */
1591         *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen);
1592         break;
1593      case GLX_MAX_PBUFFER_HEIGHT:
1594         if (!fbconfig)
1595            return GLX_BAD_ATTRIBUTE;
1596         *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen);
1597         break;
1598      case GLX_MAX_PBUFFER_PIXELS:
1599         if (!fbconfig)
1600            return GLX_BAD_ATTRIBUTE;
1601         *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) *
1602                  DisplayHeight(xmvis->display, xmvis->visinfo->screen);
1603         break;
1604      case GLX_VISUAL_ID:
1605         if (!fbconfig)
1606            return GLX_BAD_ATTRIBUTE;
1607         *value = xmvis->visinfo->visualid;
1608         break;
1609
1610#ifdef GLX_EXT_texture_from_pixmap
1611      case GLX_BIND_TO_TEXTURE_RGB_EXT:
1612         *value = True; /*XXX*/
1613         break;
1614      case GLX_BIND_TO_TEXTURE_RGBA_EXT:
1615         /* XXX review */
1616         *value = xmvis->mesa_visual.alphaBits > 0 ? True : False;
1617         break;
1618      case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
1619         *value = True; /*XXX*/
1620         break;
1621      case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
1622         *value = (GLX_TEXTURE_1D_BIT_EXT |
1623                   GLX_TEXTURE_2D_BIT_EXT |
1624                   GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/
1625         break;
1626      case GLX_Y_INVERTED_EXT:
1627         *value = True; /*XXX*/
1628         break;
1629#endif
1630
1631      default:
1632	 return GLX_BAD_ATTRIBUTE;
1633   }
1634   return Success;
1635}
1636
1637
1638int
1639glXGetConfig( Display *dpy, XVisualInfo *visinfo,
1640                   int attrib, int *value )
1641{
1642   XMesaVisual xmvis;
1643   int k;
1644   if (!dpy || !visinfo)
1645      return GLX_BAD_ATTRIBUTE;
1646
1647   xmvis = find_glx_visual( dpy, visinfo );
1648   if (!xmvis) {
1649      /* this visual wasn't obtained with glXChooseVisual */
1650      xmvis = create_glx_visual( dpy, visinfo );
1651      if (!xmvis) {
1652	 /* this visual can't be used for GL rendering */
1653	 if (attrib==GLX_USE_GL) {
1654	    *value = (int) False;
1655	    return 0;
1656	 }
1657	 else {
1658	    return GLX_BAD_VISUAL;
1659	 }
1660      }
1661   }
1662
1663   k = get_config(xmvis, attrib, value, GL_FALSE);
1664   return k;
1665}
1666
1667
1668void
1669glXWaitGL( void )
1670{
1671   XMesaContext xmesa = XMesaGetCurrentContext();
1672   XMesaFlush( xmesa );
1673}
1674
1675
1676
1677void
1678glXWaitX( void )
1679{
1680   XMesaContext xmesa = XMesaGetCurrentContext();
1681   XMesaFlush( xmesa );
1682}
1683
1684
1685static const char *
1686get_extensions( void )
1687{
1688   return EXTENSIONS;
1689}
1690
1691
1692
1693/* GLX 1.1 and later */
1694const char *
1695glXQueryExtensionsString( Display *dpy, int screen )
1696{
1697   (void) dpy;
1698   (void) screen;
1699   return get_extensions();
1700}
1701
1702
1703
1704/* GLX 1.1 and later */
1705const char *
1706glXQueryServerString( Display *dpy, int screen, int name )
1707{
1708   static char version[1000];
1709   _mesa_sprintf(version, "%d.%d %s",
1710                 SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
1711
1712   (void) dpy;
1713   (void) screen;
1714
1715   switch (name) {
1716      case GLX_EXTENSIONS:
1717         return get_extensions();
1718      case GLX_VENDOR:
1719	 return VENDOR;
1720      case GLX_VERSION:
1721	 return version;
1722      default:
1723         return NULL;
1724   }
1725}
1726
1727
1728
1729/* GLX 1.1 and later */
1730const char *
1731glXGetClientString( Display *dpy, int name )
1732{
1733   static char version[1000];
1734   _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
1735                 CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
1736
1737   (void) dpy;
1738
1739   switch (name) {
1740      case GLX_EXTENSIONS:
1741         return get_extensions();
1742      case GLX_VENDOR:
1743	 return VENDOR;
1744      case GLX_VERSION:
1745	 return version;
1746      default:
1747         return NULL;
1748   }
1749}
1750
1751
1752
1753/*
1754 * GLX 1.3 and later
1755 */
1756
1757
1758int
1759glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
1760                           int attribute, int *value )
1761{
1762   XMesaVisual v = (XMesaVisual) config;
1763   (void) dpy;
1764   (void) config;
1765
1766   if (!dpy || !config || !value)
1767      return -1;
1768
1769   return get_config(v, attribute, value, GL_TRUE);
1770}
1771
1772
1773GLXFBConfig *
1774glXGetFBConfigs( Display *dpy, int screen, int *nelements )
1775{
1776   XVisualInfo *visuals, visTemplate;
1777   const long visMask = VisualScreenMask;
1778   int i;
1779
1780   /* Get list of all X visuals */
1781   visTemplate.screen = screen;
1782   visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
1783   if (*nelements > 0) {
1784      XMesaVisual *results;
1785      results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual));
1786      if (!results) {
1787         *nelements = 0;
1788         return NULL;
1789      }
1790      for (i = 0; i < *nelements; i++) {
1791         results[i] = create_glx_visual(dpy, visuals + i);
1792      }
1793      return (GLXFBConfig *) results;
1794   }
1795   return NULL;
1796}
1797
1798
1799GLXFBConfig *
1800glXChooseFBConfig( Display *dpy, int screen,
1801                        const int *attribList, int *nitems )
1802{
1803   XMesaVisual xmvis;
1804
1805   if (!attribList || !attribList[0]) {
1806      /* return list of all configs (per GLX_SGIX_fbconfig spec) */
1807      return glXGetFBConfigs(dpy, screen, nitems);
1808   }
1809
1810   xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
1811   if (xmvis) {
1812      GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual));
1813      if (!config) {
1814         *nitems = 0;
1815         return NULL;
1816      }
1817      *nitems = 1;
1818      config[0] = (GLXFBConfig) xmvis;
1819      return (GLXFBConfig *) config;
1820   }
1821   else {
1822      *nitems = 0;
1823      return NULL;
1824   }
1825}
1826
1827
1828XVisualInfo *
1829glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
1830{
1831   if (dpy && config) {
1832      XMesaVisual xmvis = (XMesaVisual) config;
1833#if 0
1834      return xmvis->vishandle;
1835#else
1836      /* create a new vishandle - the cached one may be stale */
1837      xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
1838      if (xmvis->vishandle) {
1839         _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
1840      }
1841      return xmvis->vishandle;
1842#endif
1843   }
1844   else {
1845      return NULL;
1846   }
1847}
1848
1849
1850GLXWindow
1851glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
1852                      const int *attribList )
1853{
1854   XMesaVisual xmvis = (XMesaVisual) config;
1855   XMesaBuffer xmbuf;
1856   if (!xmvis)
1857      return 0;
1858
1859   xmbuf = XMesaCreateWindowBuffer(xmvis, win);
1860   if (!xmbuf)
1861      return 0;
1862
1863   (void) dpy;
1864   (void) attribList;  /* Ignored in GLX 1.3 */
1865
1866   return win;  /* A hack for now */
1867}
1868
1869
1870void
1871glXDestroyWindow( Display *dpy, GLXWindow window )
1872{
1873   XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window);
1874   if (b)
1875      XMesaDestroyBuffer(b);
1876   /* don't destroy X window */
1877}
1878
1879
1880/* XXX untested */
1881GLXPixmap
1882glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
1883                      const int *attribList )
1884{
1885   XMesaVisual v = (XMesaVisual) config;
1886   XMesaBuffer b;
1887   const int *attr;
1888   int target = 0, format = 0, mipmap = 0;
1889   int value;
1890
1891   if (!dpy || !config || !pixmap)
1892      return 0;
1893
1894   for (attr = attribList; attr && *attr; attr++) {
1895      switch (*attr) {
1896      case GLX_TEXTURE_FORMAT_EXT:
1897         attr++;
1898         switch (*attr) {
1899         case GLX_TEXTURE_FORMAT_NONE_EXT:
1900         case GLX_TEXTURE_FORMAT_RGB_EXT:
1901         case GLX_TEXTURE_FORMAT_RGBA_EXT:
1902            format = *attr;
1903            break;
1904         default:
1905            /* error */
1906            return 0;
1907         }
1908         break;
1909      case GLX_TEXTURE_TARGET_EXT:
1910         attr++;
1911         switch (*attr) {
1912         case GLX_TEXTURE_1D_EXT:
1913         case GLX_TEXTURE_2D_EXT:
1914         case GLX_TEXTURE_RECTANGLE_EXT:
1915            target = *attr;
1916            break;
1917         default:
1918            /* error */
1919            return 0;
1920         }
1921         break;
1922      case GLX_MIPMAP_TEXTURE_EXT:
1923         attr++;
1924         if (*attr)
1925            mipmap = 1;
1926         break;
1927      default:
1928         /* error */
1929         return 0;
1930      }
1931   }
1932
1933   if (format == GLX_TEXTURE_FORMAT_RGB_EXT) {
1934      if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT,
1935                     &value, GL_TRUE) != Success
1936          || !value) {
1937         return 0; /* error! */
1938      }
1939   }
1940   else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) {
1941      if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT,
1942                     &value, GL_TRUE) != Success
1943          || !value) {
1944         return 0; /* error! */
1945      }
1946   }
1947   if (mipmap) {
1948      if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
1949                     &value, GL_TRUE) != Success
1950          || !value) {
1951         return 0; /* error! */
1952      }
1953   }
1954   if (target == GLX_TEXTURE_1D_EXT) {
1955      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1956                     &value, GL_TRUE) != Success
1957          || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) {
1958         return 0; /* error! */
1959      }
1960   }
1961   else if (target == GLX_TEXTURE_2D_EXT) {
1962      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1963                     &value, GL_TRUE) != Success
1964          || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) {
1965         return 0; /* error! */
1966      }
1967   }
1968   if (target == GLX_TEXTURE_RECTANGLE_EXT) {
1969      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1970                     &value, GL_TRUE) != Success
1971          || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) {
1972         return 0; /* error! */
1973      }
1974   }
1975
1976   if (format || target || mipmap) {
1977      /* texture from pixmap */
1978      b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap);
1979   }
1980   else {
1981      b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
1982   }
1983   if (!b) {
1984      return 0;
1985   }
1986
1987   return pixmap;
1988}
1989
1990
1991void
1992glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
1993{
1994   XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap);
1995   if (b)
1996      XMesaDestroyBuffer(b);
1997   /* don't destroy X pixmap */
1998}
1999
2000
2001GLXPbuffer
2002glXCreatePbuffer( Display *dpy, GLXFBConfig config,
2003                       const int *attribList )
2004{
2005   XMesaVisual xmvis = (XMesaVisual) config;
2006   XMesaBuffer xmbuf;
2007   const int *attrib;
2008   int width = 0, height = 0;
2009   GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
2010
2011   (void) dpy;
2012
2013   for (attrib = attribList; *attrib; attrib++) {
2014      switch (*attrib) {
2015         case GLX_PBUFFER_WIDTH:
2016            attrib++;
2017            width = *attrib;
2018            break;
2019         case GLX_PBUFFER_HEIGHT:
2020            attrib++;
2021            height = *attrib;
2022            break;
2023         case GLX_PRESERVED_CONTENTS:
2024            attrib++;
2025            preserveContents = *attrib; /* ignored */
2026            break;
2027         case GLX_LARGEST_PBUFFER:
2028            attrib++;
2029            useLargest = *attrib; /* ignored */
2030            break;
2031         default:
2032            return 0;
2033      }
2034   }
2035
2036   /* not used at this time */
2037   (void) useLargest;
2038   (void) preserveContents;
2039
2040   if (width == 0 || height == 0)
2041      return 0;
2042
2043   xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
2044   /* A GLXPbuffer handle must be an X Drawable because that's what
2045    * glXMakeCurrent takes.
2046    */
2047   if (xmbuf)
2048      return (GLXPbuffer) xmbuf->drawable;
2049   else
2050      return 0;
2051}
2052
2053
2054void
2055glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
2056{
2057   XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
2058   if (b) {
2059      XMesaDestroyBuffer(b);
2060   }
2061}
2062
2063
2064void
2065glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
2066                       unsigned int *value )
2067{
2068   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
2069   if (!xmbuf)
2070      return;
2071
2072   switch (attribute) {
2073      case GLX_WIDTH:
2074         *value = xmesa_buffer_width(xmbuf);
2075         break;
2076      case GLX_HEIGHT:
2077         *value = xmesa_buffer_width(xmbuf);
2078         break;
2079      case GLX_PRESERVED_CONTENTS:
2080         *value = True;
2081         break;
2082      case GLX_LARGEST_PBUFFER:
2083         *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf);
2084         break;
2085      case GLX_FBCONFIG_ID:
2086         *value = xmbuf->xm_visual->visinfo->visualid;
2087         return;
2088#ifdef GLX_EXT_texture_from_pixmap
2089      case GLX_TEXTURE_FORMAT_EXT:
2090         *value = xmbuf->TextureFormat;
2091         break;
2092      case GLX_TEXTURE_TARGET_EXT:
2093         *value = xmbuf->TextureTarget;
2094         break;
2095      case GLX_MIPMAP_TEXTURE_EXT:
2096         *value = xmbuf->TextureMipmap;
2097         break;
2098#endif
2099
2100      default:
2101         return; /* raise BadValue error */
2102   }
2103}
2104
2105
2106GLXContext
2107glXCreateNewContext( Display *dpy, GLXFBConfig config,
2108                          int renderType, GLXContext shareList, Bool direct )
2109{
2110   struct fake_glx_context *glxCtx;
2111   struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList;
2112   XMesaVisual xmvis = (XMesaVisual) config;
2113
2114   if (!dpy || !config ||
2115       (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
2116      return 0;
2117
2118   glxCtx = CALLOC_STRUCT(fake_glx_context);
2119   if (!glxCtx)
2120      return 0;
2121
2122   /* deallocate unused windows/buffers */
2123   XMesaGarbageCollect();
2124
2125   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
2126                                   shareCtx ? shareCtx->xmesaContext : NULL);
2127   if (!glxCtx->xmesaContext) {
2128      _mesa_free(glxCtx);
2129      return NULL;
2130   }
2131
2132   glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
2133   glxCtx->glxContext.currentDpy = dpy;
2134   glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */
2135
2136   assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
2137
2138   return (GLXContext) glxCtx;
2139}
2140
2141
2142int
2143glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
2144{
2145   struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
2146   XMesaContext xmctx = glxCtx->xmesaContext;
2147
2148   (void) dpy;
2149   (void) ctx;
2150
2151   switch (attribute) {
2152   case GLX_FBCONFIG_ID:
2153      *value = xmctx->xm_visual->visinfo->visualid;
2154      break;
2155   case GLX_RENDER_TYPE:
2156      if (xmctx->xm_visual->mesa_visual.rgbMode)
2157         *value = GLX_RGBA_BIT;
2158      else
2159         *value = GLX_COLOR_INDEX_BIT;
2160      break;
2161   case GLX_SCREEN:
2162      *value = 0;
2163      return Success;
2164   default:
2165      return GLX_BAD_ATTRIBUTE;
2166   }
2167   return 0;
2168}
2169
2170
2171void
2172glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
2173{
2174   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
2175   if (xmbuf)
2176      xmbuf->selectedEvents = mask;
2177}
2178
2179
2180void
2181glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
2182                          unsigned long *mask )
2183{
2184   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
2185   if (xmbuf)
2186      *mask = xmbuf->selectedEvents;
2187   else
2188      *mask = 0;
2189}
2190
2191
2192
2193/*** GLX_SGI_swap_control ***/
2194
2195int
2196glXSwapIntervalSGI(int interval)
2197{
2198   (void) interval;
2199   return 0;
2200}
2201
2202
2203
2204/*** GLX_SGI_video_sync ***/
2205
2206static unsigned int FrameCounter = 0;
2207
2208int
2209glXGetVideoSyncSGI(unsigned int *count)
2210{
2211   /* this is a bogus implementation */
2212   *count = FrameCounter++;
2213   return 0;
2214}
2215
2216int
2217glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
2218{
2219   if (divisor <= 0 || remainder < 0)
2220      return GLX_BAD_VALUE;
2221   /* this is a bogus implementation */
2222   FrameCounter++;
2223   while (FrameCounter % divisor != remainder)
2224      FrameCounter++;
2225   *count = FrameCounter;
2226   return 0;
2227}
2228
2229
2230
2231/*** GLX_SGI_make_current_read ***/
2232
2233Bool
2234glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
2235{
2236   return glXMakeContextCurrent( dpy, draw, read, ctx );
2237}
2238
2239/* not used
2240static GLXDrawable
2241glXGetCurrentReadDrawableSGI(void)
2242{
2243   return 0;
2244}
2245*/
2246
2247
2248/*** GLX_SGIX_video_source ***/
2249#if defined(_VL_H)
2250
2251GLXVideoSourceSGIX
2252glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, 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
2263void
2264glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
2265{
2266   (void) dpy;
2267   (void) src;
2268}
2269
2270#endif
2271
2272
2273/*** GLX_EXT_import_context ***/
2274
2275void
2276glXFreeContextEXT(Display *dpy, GLXContext context)
2277{
2278   (void) dpy;
2279   (void) context;
2280}
2281
2282GLXContextID
2283glXGetContextIDEXT(const GLXContext context)
2284{
2285   (void) context;
2286   return 0;
2287}
2288
2289GLXContext
2290glXImportContextEXT(Display *dpy, GLXContextID contextID)
2291{
2292   (void) dpy;
2293   (void) contextID;
2294   return 0;
2295}
2296
2297int
2298glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
2299{
2300   (void) dpy;
2301   (void) context;
2302   (void) attribute;
2303   (void) value;
2304   return 0;
2305}
2306
2307
2308
2309/*** GLX_SGIX_fbconfig ***/
2310
2311int
2312glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
2313{
2314   return glXGetFBConfigAttrib(dpy, config, attribute, value);
2315}
2316
2317GLXFBConfigSGIX *
2318glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
2319{
2320   return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements);
2321}
2322
2323
2324GLXPixmap
2325glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
2326{
2327   XMesaVisual xmvis = (XMesaVisual) config;
2328   XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
2329   return xmbuf->drawable; /* need to return an X ID */
2330}
2331
2332
2333GLXContext
2334glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
2335{
2336   XMesaVisual xmvis = (XMesaVisual) config;
2337   struct fake_glx_context *glxCtx;
2338   struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
2339
2340   glxCtx = CALLOC_STRUCT(fake_glx_context);
2341   if (!glxCtx)
2342      return 0;
2343
2344   /* deallocate unused windows/buffers */
2345   XMesaGarbageCollect();
2346
2347   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
2348                                   shareCtx ? shareCtx->xmesaContext : NULL);
2349   if (!glxCtx->xmesaContext) {
2350      _mesa_free(glxCtx);
2351      return NULL;
2352   }
2353
2354   glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
2355   glxCtx->glxContext.currentDpy = dpy;
2356   glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */
2357
2358   assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
2359
2360   return (GLXContext) glxCtx;
2361}
2362
2363
2364XVisualInfo *
2365glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
2366{
2367   return glXGetVisualFromFBConfig(dpy, config);
2368}
2369
2370
2371GLXFBConfigSGIX
2372glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
2373{
2374   XMesaVisual xmvis = find_glx_visual(dpy, vis);
2375   if (!xmvis) {
2376      /* This visual wasn't found with glXChooseVisual() */
2377      xmvis = create_glx_visual(dpy, vis);
2378   }
2379
2380   return (GLXFBConfigSGIX) xmvis;
2381}
2382
2383
2384
2385/*** GLX_SGIX_pbuffer ***/
2386
2387GLXPbufferSGIX
2388glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
2389                             unsigned int width, unsigned int height,
2390                             int *attribList)
2391{
2392   XMesaVisual xmvis = (XMesaVisual) config;
2393   XMesaBuffer xmbuf;
2394   const int *attrib;
2395   GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
2396
2397   (void) dpy;
2398
2399   for (attrib = attribList; attrib && *attrib; attrib++) {
2400      switch (*attrib) {
2401         case GLX_PRESERVED_CONTENTS_SGIX:
2402            attrib++;
2403            preserveContents = *attrib; /* ignored */
2404            break;
2405         case GLX_LARGEST_PBUFFER_SGIX:
2406            attrib++;
2407            useLargest = *attrib; /* ignored */
2408            break;
2409         default:
2410            return 0;
2411      }
2412   }
2413
2414   /* not used at this time */
2415   (void) useLargest;
2416   (void) preserveContents;
2417
2418   xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
2419   /* A GLXPbuffer handle must be an X Drawable because that's what
2420    * glXMakeCurrent takes.
2421    */
2422   return (GLXPbuffer) xmbuf->drawable;
2423}
2424
2425
2426void
2427glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
2428{
2429   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
2430   if (xmbuf) {
2431      XMesaDestroyBuffer(xmbuf);
2432   }
2433}
2434
2435
2436int
2437glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
2438{
2439   const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
2440
2441   if (!xmbuf) {
2442      /* Generate GLXBadPbufferSGIX for bad pbuffer */
2443      return 0;
2444   }
2445
2446   switch (attribute) {
2447      case GLX_PRESERVED_CONTENTS_SGIX:
2448         *value = True;
2449         break;
2450      case GLX_LARGEST_PBUFFER_SGIX:
2451         *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf);
2452         break;
2453      case GLX_WIDTH_SGIX:
2454         *value = xmesa_buffer_width(xmbuf);
2455         break;
2456      case GLX_HEIGHT_SGIX:
2457         *value = xmesa_buffer_height(xmbuf);
2458         break;
2459      case GLX_EVENT_MASK_SGIX:
2460         *value = 0;  /* XXX might be wrong */
2461         break;
2462      default:
2463         *value = 0;
2464   }
2465   return 0;
2466}
2467
2468
2469void
2470glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
2471{
2472   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
2473   if (xmbuf) {
2474      /* Note: we'll never generate clobber events */
2475      xmbuf->selectedEvents = mask;
2476   }
2477}
2478
2479
2480void
2481glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
2482{
2483   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
2484   if (xmbuf) {
2485      *mask = xmbuf->selectedEvents;
2486   }
2487   else {
2488      *mask = 0;
2489   }
2490}
2491
2492
2493
2494/*** GLX_SGI_cushion ***/
2495
2496void
2497glXCushionSGI(Display *dpy, Window win, float cushion)
2498{
2499   (void) dpy;
2500   (void) win;
2501   (void) cushion;
2502}
2503
2504
2505
2506/*** GLX_SGIX_video_resize ***/
2507
2508int
2509glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
2510{
2511   (void) dpy;
2512   (void) screen;
2513   (void) channel;
2514   (void) window;
2515   return 0;
2516}
2517
2518int
2519glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
2520{
2521   (void) dpy;
2522   (void) screen;
2523   (void) channel;
2524   (void) x;
2525   (void) y;
2526   (void) w;
2527   (void) h;
2528   return 0;
2529}
2530
2531int
2532glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
2533{
2534   (void) dpy;
2535   (void) screen;
2536   (void) channel;
2537   (void) x;
2538   (void) y;
2539   (void) w;
2540   (void) h;
2541   return 0;
2542}
2543
2544int
2545glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
2546{
2547   (void) dpy;
2548   (void) screen;
2549   (void) channel;
2550   (void) dx;
2551   (void) dy;
2552   (void) dw;
2553   (void) dh;
2554   return 0;
2555}
2556
2557int
2558glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
2559{
2560   (void) dpy;
2561   (void) screen;
2562   (void) channel;
2563   (void) synctype;
2564   return 0;
2565}
2566
2567
2568
2569/*** GLX_SGIX_dmbuffer **/
2570
2571#if defined(_DM_BUFFER_H_)
2572Bool
2573glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
2574{
2575   (void) dpy;
2576   (void) pbuffer;
2577   (void) params;
2578   (void) dmbuffer;
2579   return False;
2580}
2581#endif
2582
2583
2584/*** GLX_SGIX_swap_group ***/
2585
2586void
2587glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
2588{
2589   (void) dpy;
2590   (void) drawable;
2591   (void) member;
2592}
2593
2594
2595
2596/*** GLX_SGIX_swap_barrier ***/
2597
2598void
2599glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
2600{
2601   (void) dpy;
2602   (void) drawable;
2603   (void) barrier;
2604}
2605
2606Bool
2607glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
2608{
2609   (void) dpy;
2610   (void) screen;
2611   (void) max;
2612   return False;
2613}
2614
2615
2616
2617/*** GLX_SUN_get_transparent_index ***/
2618
2619Status
2620glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, 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 */
2637Bool
2638glXReleaseBuffersMESA( 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
2650void
2651glXBindTexImageEXT(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
2659void
2660glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
2661{
2662   XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
2663   if (b)
2664      XMesaReleaseTexImage(dpy, b, buffer);
2665}
2666