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