1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 24848b8605Smrg */ 25848b8605Smrg 26848b8605Smrg 27848b8605Smrg/* 28848b8605Smrg * This is an emulation of the GLX API which allows Mesa/GLX-based programs 29848b8605Smrg * to run on X servers which do not have the real GLX extension. 30848b8605Smrg * 31848b8605Smrg * Thanks to the contributors: 32848b8605Smrg * 33848b8605Smrg * Initial version: Philip Brown (phil@bolthole.com) 34848b8605Smrg * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu) 35848b8605Smrg * Further visual-handling refinements: Wolfram Gloger 36848b8605Smrg * (wmglo@Dent.MED.Uni-Muenchen.DE). 37848b8605Smrg * 38848b8605Smrg * Notes: 39848b8605Smrg * Don't be fooled, stereo isn't supported yet. 40848b8605Smrg */ 41848b8605Smrg 42848b8605Smrg 43b8e80941Smrg#include <string.h> 44b8e80941Smrg#include <stdio.h> 45848b8605Smrg#include "glxheader.h" 46848b8605Smrg#include "glxapi.h" 47848b8605Smrg#include "main/context.h" 48848b8605Smrg#include "main/config.h" 49848b8605Smrg#include "main/macros.h" 50848b8605Smrg#include "main/imports.h" 51848b8605Smrg#include "main/mtypes.h" 52848b8605Smrg#include "main/version.h" 53848b8605Smrg#include "xfonts.h" 54848b8605Smrg#include "xmesaP.h" 55b8e80941Smrg#include "util/u_math.h" 56848b8605Smrg 57848b8605Smrg/* This indicates the client-side GLX API and GLX encoder version. */ 58848b8605Smrg#define CLIENT_MAJOR_VERSION 1 59848b8605Smrg#define CLIENT_MINOR_VERSION 4 /* but don't have 1.3's pbuffers, etc yet */ 60848b8605Smrg 61848b8605Smrg/* This indicates the server-side GLX decoder version. 62848b8605Smrg * GLX 1.4 indicates OpenGL 1.3 support 63848b8605Smrg */ 64848b8605Smrg#define SERVER_MAJOR_VERSION 1 65848b8605Smrg#define SERVER_MINOR_VERSION 4 66848b8605Smrg 67848b8605Smrg/* This is appended onto the glXGetClient/ServerString version strings. */ 68848b8605Smrg#define MESA_GLX_VERSION "Mesa " PACKAGE_VERSION 69848b8605Smrg 70848b8605Smrg/* Who implemented this GLX? */ 71848b8605Smrg#define VENDOR "Brian Paul" 72848b8605Smrg 73848b8605Smrg#define EXTENSIONS \ 74848b8605Smrg "GLX_MESA_set_3dfx_mode " \ 75848b8605Smrg "GLX_MESA_copy_sub_buffer " \ 76848b8605Smrg "GLX_MESA_pixmap_colormap " \ 77848b8605Smrg "GLX_MESA_release_buffers " \ 78b8e80941Smrg "GLX_ARB_create_context " \ 79848b8605Smrg "GLX_ARB_get_proc_address " \ 80848b8605Smrg "GLX_EXT_texture_from_pixmap " \ 81848b8605Smrg "GLX_EXT_visual_info " \ 82848b8605Smrg "GLX_EXT_visual_rating " \ 83848b8605Smrg /*"GLX_SGI_video_sync "*/ \ 84848b8605Smrg "GLX_SGIX_fbconfig " \ 85848b8605Smrg "GLX_SGIX_pbuffer " 86848b8605Smrg 87848b8605Smrg 88848b8605Smrg 89848b8605Smrg/**********************************************************************/ 90848b8605Smrg/*** GLX Visual Code ***/ 91848b8605Smrg/**********************************************************************/ 92848b8605Smrg 93848b8605Smrg#define DONT_CARE -1 94848b8605Smrg 95848b8605Smrg 96848b8605Smrgstatic XMesaVisual *VisualTable = NULL; 97848b8605Smrgstatic int NumVisuals = 0; 98848b8605Smrg 99848b8605Smrg 100848b8605Smrg/* 101848b8605Smrg * This struct and some code fragments borrowed 102848b8605Smrg * from Mark Kilgard's GLUT library. 103848b8605Smrg */ 104848b8605Smrgtypedef struct _OverlayInfo { 105848b8605Smrg /* Avoid 64-bit portability problems by being careful to use 106848b8605Smrg longs due to the way XGetWindowProperty is specified. Note 107848b8605Smrg that these parameters are passed as CARD32s over X 108848b8605Smrg protocol. */ 109848b8605Smrg unsigned long overlay_visual; 110848b8605Smrg long transparent_type; 111848b8605Smrg long value; 112848b8605Smrg long layer; 113848b8605Smrg} OverlayInfo; 114848b8605Smrg 115848b8605Smrg 116848b8605Smrg 117848b8605Smrg/* Macro to handle c_class vs class field name in XVisualInfo struct */ 118848b8605Smrg#if defined(__cplusplus) || defined(c_plusplus) 119848b8605Smrg#define CLASS c_class 120848b8605Smrg#else 121848b8605Smrg#define CLASS class 122848b8605Smrg#endif 123848b8605Smrg 124848b8605Smrg 125848b8605Smrg 126848b8605Smrg/* 127848b8605Smrg * Test if the given XVisualInfo is usable for Mesa rendering. 128848b8605Smrg */ 129848b8605Smrgstatic GLboolean 130848b8605Smrgis_usable_visual( XVisualInfo *vinfo ) 131848b8605Smrg{ 132848b8605Smrg switch (vinfo->CLASS) { 133848b8605Smrg case StaticGray: 134848b8605Smrg case GrayScale: 135848b8605Smrg /* Any StaticGray/GrayScale visual works in RGB or CI mode */ 136848b8605Smrg return GL_TRUE; 137848b8605Smrg case StaticColor: 138848b8605Smrg case PseudoColor: 139848b8605Smrg /* Color-index rendering is not supported. */ 140848b8605Smrg return GL_FALSE; 141848b8605Smrg case TrueColor: 142848b8605Smrg case DirectColor: 143848b8605Smrg /* Any depth of TrueColor or DirectColor works in RGB mode */ 144848b8605Smrg return GL_TRUE; 145848b8605Smrg default: 146848b8605Smrg /* This should never happen */ 147848b8605Smrg return GL_FALSE; 148848b8605Smrg } 149848b8605Smrg} 150848b8605Smrg 151848b8605Smrg 152848b8605Smrg 153848b8605Smrg/** 154848b8605Smrg * Get an array OverlayInfo records for specified screen. 155848b8605Smrg * \param dpy the display 156848b8605Smrg * \param screen screen number 157848b8605Smrg * \param numOverlays returns numver of OverlayInfo records 158848b8605Smrg * \return pointer to OverlayInfo array, free with XFree() 159848b8605Smrg */ 160848b8605Smrgstatic OverlayInfo * 161848b8605SmrgGetOverlayInfo(Display *dpy, int screen, int *numOverlays) 162848b8605Smrg{ 163848b8605Smrg Atom overlayVisualsAtom; 164848b8605Smrg Atom actualType; 165848b8605Smrg Status status; 166848b8605Smrg unsigned char *ovInfo; 167848b8605Smrg unsigned long sizeData, bytesLeft; 168848b8605Smrg int actualFormat; 169848b8605Smrg 170848b8605Smrg /* 171848b8605Smrg * The SERVER_OVERLAY_VISUALS property on the root window contains 172848b8605Smrg * a list of overlay visuals. Get that list now. 173848b8605Smrg */ 174848b8605Smrg overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); 175848b8605Smrg if (overlayVisualsAtom == None) { 176848b8605Smrg return 0; 177848b8605Smrg } 178848b8605Smrg 179848b8605Smrg status = XGetWindowProperty(dpy, RootWindow(dpy, screen), 180848b8605Smrg overlayVisualsAtom, 0L, (long) 10000, False, 181848b8605Smrg overlayVisualsAtom, &actualType, &actualFormat, 182848b8605Smrg &sizeData, &bytesLeft, 183848b8605Smrg &ovInfo); 184848b8605Smrg 185848b8605Smrg if (status != Success || actualType != overlayVisualsAtom || 186848b8605Smrg actualFormat != 32 || sizeData < 4) { 187848b8605Smrg /* something went wrong */ 188848b8605Smrg free((void *) ovInfo); 189848b8605Smrg *numOverlays = 0; 190848b8605Smrg return NULL; 191848b8605Smrg } 192848b8605Smrg 193848b8605Smrg *numOverlays = sizeData / 4; 194848b8605Smrg return (OverlayInfo *) ovInfo; 195848b8605Smrg} 196848b8605Smrg 197848b8605Smrg 198848b8605Smrg 199848b8605Smrg/** 200848b8605Smrg * Return the level (overlay, normal, underlay) of a given XVisualInfo. 201848b8605Smrg * Input: dpy - the X display 202848b8605Smrg * vinfo - the XVisualInfo to test 203848b8605Smrg * Return: level of the visual: 204848b8605Smrg * 0 = normal planes 205848b8605Smrg * >0 = overlay planes 206848b8605Smrg * <0 = underlay planes 207848b8605Smrg */ 208848b8605Smrgstatic int 209848b8605Smrglevel_of_visual( Display *dpy, XVisualInfo *vinfo ) 210848b8605Smrg{ 211848b8605Smrg OverlayInfo *overlay_info; 212848b8605Smrg int numOverlaysPerScreen, i; 213848b8605Smrg 214848b8605Smrg overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); 215848b8605Smrg if (!overlay_info) { 216848b8605Smrg return 0; 217848b8605Smrg } 218848b8605Smrg 219848b8605Smrg /* search the overlay visual list for the visual ID of interest */ 220848b8605Smrg for (i = 0; i < numOverlaysPerScreen; i++) { 221848b8605Smrg const OverlayInfo *ov = overlay_info + i; 222848b8605Smrg if (ov->overlay_visual == vinfo->visualid) { 223848b8605Smrg /* found the visual */ 224848b8605Smrg if (/*ov->transparent_type==1 &&*/ ov->layer!=0) { 225848b8605Smrg int level = ov->layer; 226848b8605Smrg free((void *) overlay_info); 227848b8605Smrg return level; 228848b8605Smrg } 229848b8605Smrg else { 230848b8605Smrg free((void *) overlay_info); 231848b8605Smrg return 0; 232848b8605Smrg } 233848b8605Smrg } 234848b8605Smrg } 235848b8605Smrg 236848b8605Smrg /* The visual ID was not found in the overlay list. */ 237848b8605Smrg free((void *) overlay_info); 238848b8605Smrg return 0; 239848b8605Smrg} 240848b8605Smrg 241848b8605Smrg 242848b8605Smrg 243848b8605Smrg 244848b8605Smrg/* 245848b8605Smrg * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the 246848b8605Smrg * configuration in our list of GLX visuals. 247848b8605Smrg */ 248848b8605Smrgstatic XMesaVisual 249848b8605Smrgsave_glx_visual( Display *dpy, XVisualInfo *vinfo, 250848b8605Smrg GLboolean alphaFlag, GLboolean dbFlag, 251848b8605Smrg GLboolean stereoFlag, 252848b8605Smrg GLint depth_size, GLint stencil_size, 253848b8605Smrg GLint accumRedSize, GLint accumGreenSize, 254848b8605Smrg GLint accumBlueSize, GLint accumAlphaSize, 255848b8605Smrg GLint level, GLint numAuxBuffers ) 256848b8605Smrg{ 257848b8605Smrg GLboolean ximageFlag = GL_TRUE; 258848b8605Smrg XMesaVisual xmvis; 259848b8605Smrg GLint i; 260848b8605Smrg 261848b8605Smrg if (dbFlag) { 262848b8605Smrg /* Check if the MESA_BACK_BUFFER env var is set */ 263b8e80941Smrg char *backbuffer = getenv("MESA_BACK_BUFFER"); 264848b8605Smrg if (backbuffer) { 265848b8605Smrg if (backbuffer[0]=='p' || backbuffer[0]=='P') { 266848b8605Smrg ximageFlag = GL_FALSE; 267848b8605Smrg } 268848b8605Smrg else if (backbuffer[0]=='x' || backbuffer[0]=='X') { 269848b8605Smrg ximageFlag = GL_TRUE; 270848b8605Smrg } 271848b8605Smrg else { 272848b8605Smrg _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage."); 273848b8605Smrg } 274848b8605Smrg } 275848b8605Smrg } 276848b8605Smrg 277848b8605Smrg if (stereoFlag) { 278848b8605Smrg /* stereo not supported */ 279848b8605Smrg return NULL; 280848b8605Smrg } 281848b8605Smrg 282848b8605Smrg 283848b8605Smrg /* Force the visual to have an alpha channel */ 284b8e80941Smrg if (getenv("MESA_GLX_FORCE_ALPHA")) 285848b8605Smrg alphaFlag = GL_TRUE; 286848b8605Smrg 287848b8605Smrg /* First check if a matching visual is already in the list */ 288848b8605Smrg for (i=0; i<NumVisuals; i++) { 289848b8605Smrg XMesaVisual v = VisualTable[i]; 290848b8605Smrg if (v->display == dpy 291848b8605Smrg && v->mesa_visual.level == level 292848b8605Smrg && v->mesa_visual.numAuxBuffers == numAuxBuffers 293848b8605Smrg && v->ximage_flag == ximageFlag 294848b8605Smrg && v->mesa_visual.doubleBufferMode == dbFlag 295848b8605Smrg && v->mesa_visual.stereoMode == stereoFlag 296848b8605Smrg && (v->mesa_visual.alphaBits > 0) == alphaFlag 297848b8605Smrg && (v->mesa_visual.depthBits >= depth_size || depth_size == 0) 298848b8605Smrg && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0) 299848b8605Smrg && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0) 300848b8605Smrg && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0) 301848b8605Smrg && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0) 302848b8605Smrg && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) { 303b8e80941Smrg /* now compare visual IDs */ 304b8e80941Smrg if (v->visinfo->visualid == vinfo->visualid) { 305848b8605Smrg return v; 306848b8605Smrg } 307848b8605Smrg } 308848b8605Smrg } 309848b8605Smrg 310848b8605Smrg /* Create a new visual and add it to the list. */ 311848b8605Smrg 312848b8605Smrg xmvis = XMesaCreateVisual( dpy, vinfo, GL_TRUE, alphaFlag, dbFlag, 313848b8605Smrg stereoFlag, ximageFlag, 314848b8605Smrg depth_size, stencil_size, 315848b8605Smrg accumRedSize, accumBlueSize, 316848b8605Smrg accumBlueSize, accumAlphaSize, 0, level, 317848b8605Smrg GLX_NONE_EXT ); 318848b8605Smrg if (xmvis) { 319848b8605Smrg /* Allocate more space for additional visual */ 320b8e80941Smrg VisualTable = realloc(VisualTable, sizeof(XMesaVisual) * (NumVisuals + 1)); 321848b8605Smrg /* add xmvis to the list */ 322848b8605Smrg VisualTable[NumVisuals] = xmvis; 323848b8605Smrg NumVisuals++; 324848b8605Smrg /* XXX minor hack, because XMesaCreateVisual doesn't support an 325848b8605Smrg * aux buffers parameter. 326848b8605Smrg */ 327848b8605Smrg xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; 328848b8605Smrg } 329848b8605Smrg return xmvis; 330848b8605Smrg} 331848b8605Smrg 332848b8605Smrg 333848b8605Smrg/** 334848b8605Smrg * Return the default number of bits for the Z buffer. 335848b8605Smrg * If defined, use the MESA_GLX_DEPTH_BITS env var value. 336848b8605Smrg * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. 337848b8605Smrg * XXX probably do the same thing for stencil, accum, etc. 338848b8605Smrg */ 339848b8605Smrgstatic GLint 340848b8605Smrgdefault_depth_bits(void) 341848b8605Smrg{ 342848b8605Smrg int zBits; 343b8e80941Smrg const char *zEnv = getenv("MESA_GLX_DEPTH_BITS"); 344848b8605Smrg if (zEnv) 345848b8605Smrg zBits = atoi(zEnv); 346848b8605Smrg else 347848b8605Smrg zBits = DEFAULT_SOFTWARE_DEPTH_BITS; 348848b8605Smrg return zBits; 349848b8605Smrg} 350848b8605Smrg 351848b8605Smrgstatic GLint 352848b8605Smrgdefault_alpha_bits(void) 353848b8605Smrg{ 354848b8605Smrg int aBits; 355b8e80941Smrg const char *aEnv = getenv("MESA_GLX_ALPHA_BITS"); 356848b8605Smrg if (aEnv) 357848b8605Smrg aBits = atoi(aEnv); 358848b8605Smrg else 359848b8605Smrg aBits = 0; 360848b8605Smrg return aBits; 361848b8605Smrg} 362848b8605Smrg 363848b8605Smrgstatic GLint 364848b8605Smrgdefault_accum_bits(void) 365848b8605Smrg{ 366848b8605Smrg return 16; 367848b8605Smrg} 368848b8605Smrg 369848b8605Smrg 370848b8605Smrg 371848b8605Smrg/* 372848b8605Smrg * Create a GLX visual from a regular XVisualInfo. 373848b8605Smrg * This is called when Fake GLX is given an XVisualInfo which wasn't 374848b8605Smrg * returned by glXChooseVisual. Since this is the first time we're 375848b8605Smrg * considering this visual we'll take a guess at reasonable values 376848b8605Smrg * for depth buffer size, stencil size, accum size, etc. 377848b8605Smrg * This is the best we can do with a client-side emulation of GLX. 378848b8605Smrg */ 379848b8605Smrgstatic XMesaVisual 380848b8605Smrgcreate_glx_visual( Display *dpy, XVisualInfo *visinfo ) 381848b8605Smrg{ 382848b8605Smrg int vislevel; 383848b8605Smrg GLint zBits = default_depth_bits(); 384848b8605Smrg GLint accBits = default_accum_bits(); 385848b8605Smrg GLboolean alphaFlag = default_alpha_bits() > 0; 386848b8605Smrg 387848b8605Smrg vislevel = level_of_visual( dpy, visinfo ); 388848b8605Smrg if (vislevel) { 389848b8605Smrg /* Color-index rendering to overlays is not supported. */ 390848b8605Smrg return NULL; 391848b8605Smrg } 392848b8605Smrg else if (is_usable_visual( visinfo )) { 393848b8605Smrg /* Configure this visual as RGB, double-buffered, depth-buffered. */ 394848b8605Smrg /* This is surely wrong for some people's needs but what else */ 395848b8605Smrg /* can be done? They should use glXChooseVisual(). */ 396848b8605Smrg return save_glx_visual( dpy, visinfo, 397848b8605Smrg alphaFlag, /* alpha */ 398848b8605Smrg GL_TRUE, /* double */ 399848b8605Smrg GL_FALSE, /* stereo */ 400848b8605Smrg zBits, 401848b8605Smrg 8, /* stencil bits */ 402848b8605Smrg accBits, /* r */ 403848b8605Smrg accBits, /* g */ 404848b8605Smrg accBits, /* b */ 405848b8605Smrg accBits, /* a */ 406848b8605Smrg 0, /* level */ 407848b8605Smrg 0 /* numAux */ 408848b8605Smrg ); 409848b8605Smrg } 410848b8605Smrg else { 411848b8605Smrg _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n"); 412848b8605Smrg return NULL; 413848b8605Smrg } 414848b8605Smrg} 415848b8605Smrg 416848b8605Smrg 417848b8605Smrg 418848b8605Smrg/* 419848b8605Smrg * Find the GLX visual associated with an XVisualInfo. 420848b8605Smrg */ 421848b8605Smrgstatic XMesaVisual 422848b8605Smrgfind_glx_visual( Display *dpy, XVisualInfo *vinfo ) 423848b8605Smrg{ 424848b8605Smrg int i; 425848b8605Smrg 426848b8605Smrg /* try to match visual id */ 427848b8605Smrg for (i=0;i<NumVisuals;i++) { 428848b8605Smrg if (VisualTable[i]->display==dpy 429848b8605Smrg && VisualTable[i]->visinfo->visualid == vinfo->visualid) { 430848b8605Smrg return VisualTable[i]; 431848b8605Smrg } 432848b8605Smrg } 433848b8605Smrg 434848b8605Smrg return NULL; 435848b8605Smrg} 436848b8605Smrg 437848b8605Smrg 438848b8605Smrg 439848b8605Smrg/** 440848b8605Smrg * Return the transparent pixel value for a GLX visual. 441848b8605Smrg * Input: glxvis - the glx_visual 442848b8605Smrg * Return: a pixel value or -1 if no transparent pixel 443848b8605Smrg */ 444848b8605Smrgstatic int 445848b8605Smrgtransparent_pixel( XMesaVisual glxvis ) 446848b8605Smrg{ 447848b8605Smrg Display *dpy = glxvis->display; 448848b8605Smrg XVisualInfo *vinfo = glxvis->visinfo; 449848b8605Smrg OverlayInfo *overlay_info; 450848b8605Smrg int numOverlaysPerScreen, i; 451848b8605Smrg 452848b8605Smrg overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); 453848b8605Smrg if (!overlay_info) { 454848b8605Smrg return -1; 455848b8605Smrg } 456848b8605Smrg 457848b8605Smrg for (i = 0; i < numOverlaysPerScreen; i++) { 458848b8605Smrg const OverlayInfo *ov = overlay_info + i; 459848b8605Smrg if (ov->overlay_visual == vinfo->visualid) { 460848b8605Smrg /* found it! */ 461848b8605Smrg if (ov->transparent_type == 0) { 462848b8605Smrg /* type 0 indicates no transparency */ 463848b8605Smrg free((void *) overlay_info); 464848b8605Smrg return -1; 465848b8605Smrg } 466848b8605Smrg else { 467848b8605Smrg /* ov->value is the transparent pixel */ 468848b8605Smrg free((void *) overlay_info); 469848b8605Smrg return ov->value; 470848b8605Smrg } 471848b8605Smrg } 472848b8605Smrg } 473848b8605Smrg 474848b8605Smrg /* The visual ID was not found in the overlay list. */ 475848b8605Smrg free((void *) overlay_info); 476848b8605Smrg return -1; 477848b8605Smrg} 478848b8605Smrg 479848b8605Smrg 480848b8605Smrg 481848b8605Smrg/** 482848b8605Smrg * Try to get an X visual which matches the given arguments. 483848b8605Smrg */ 484848b8605Smrgstatic XVisualInfo * 485848b8605Smrgget_visual( Display *dpy, int scr, unsigned int depth, int xclass ) 486848b8605Smrg{ 487848b8605Smrg XVisualInfo temp, *vis; 488848b8605Smrg long mask; 489848b8605Smrg int n; 490848b8605Smrg unsigned int default_depth; 491848b8605Smrg int default_class; 492848b8605Smrg 493848b8605Smrg mask = VisualScreenMask | VisualDepthMask | VisualClassMask; 494848b8605Smrg temp.screen = scr; 495848b8605Smrg temp.depth = depth; 496848b8605Smrg temp.CLASS = xclass; 497848b8605Smrg 498848b8605Smrg default_depth = DefaultDepth(dpy,scr); 499848b8605Smrg default_class = DefaultVisual(dpy,scr)->CLASS; 500848b8605Smrg 501848b8605Smrg if (depth==default_depth && xclass==default_class) { 502848b8605Smrg /* try to get root window's visual */ 503848b8605Smrg temp.visualid = DefaultVisual(dpy,scr)->visualid; 504848b8605Smrg mask |= VisualIDMask; 505848b8605Smrg } 506848b8605Smrg 507848b8605Smrg vis = XGetVisualInfo( dpy, mask, &temp, &n ); 508848b8605Smrg 509848b8605Smrg /* In case bits/pixel > 24, make sure color channels are still <=8 bits. 510848b8605Smrg * An SGI Infinite Reality system, for example, can have 30bpp pixels: 511848b8605Smrg * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel. 512848b8605Smrg */ 513848b8605Smrg if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) { 514b8e80941Smrg if (util_bitcount((GLuint) vis->red_mask ) <= 8 && 515b8e80941Smrg util_bitcount((GLuint) vis->green_mask) <= 8 && 516b8e80941Smrg util_bitcount((GLuint) vis->blue_mask ) <= 8) { 517848b8605Smrg return vis; 518848b8605Smrg } 519848b8605Smrg else { 520848b8605Smrg free((void *) vis); 521848b8605Smrg return NULL; 522848b8605Smrg } 523848b8605Smrg } 524848b8605Smrg 525848b8605Smrg return vis; 526848b8605Smrg} 527848b8605Smrg 528848b8605Smrg 529848b8605Smrg 530848b8605Smrg/* 531848b8605Smrg * Retrieve the value of the given environment variable and find 532848b8605Smrg * the X visual which matches it. 533848b8605Smrg * Input: dpy - the display 534848b8605Smrg * screen - the screen number 535848b8605Smrg * varname - the name of the environment variable 536848b8605Smrg * Return: an XVisualInfo pointer to NULL if error. 537848b8605Smrg */ 538848b8605Smrgstatic XVisualInfo * 539848b8605Smrgget_env_visual(Display *dpy, int scr, const char *varname) 540848b8605Smrg{ 541848b8605Smrg char value[100], type[100]; 542848b8605Smrg int depth, xclass = -1; 543848b8605Smrg XVisualInfo *vis; 544848b8605Smrg 545b8e80941Smrg if (!getenv( varname )) { 546848b8605Smrg return NULL; 547848b8605Smrg } 548848b8605Smrg 549b8e80941Smrg strncpy( value, getenv(varname), 100 ); 550848b8605Smrg value[99] = 0; 551848b8605Smrg 552848b8605Smrg sscanf( value, "%s %d", type, &depth ); 553848b8605Smrg 554848b8605Smrg if (strcmp(type,"TrueColor")==0) xclass = TrueColor; 555848b8605Smrg else if (strcmp(type,"DirectColor")==0) xclass = DirectColor; 556848b8605Smrg else if (strcmp(type,"GrayScale")==0) xclass = GrayScale; 557848b8605Smrg else if (strcmp(type,"StaticGray")==0) xclass = StaticGray; 558848b8605Smrg 559848b8605Smrg if (xclass>-1 && depth>0) { 560848b8605Smrg vis = get_visual( dpy, scr, depth, xclass ); 561848b8605Smrg if (vis) { 562848b8605Smrg return vis; 563848b8605Smrg } 564848b8605Smrg } 565848b8605Smrg 566848b8605Smrg _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.", 567848b8605Smrg type, depth); 568848b8605Smrg 569848b8605Smrg return NULL; 570848b8605Smrg} 571848b8605Smrg 572848b8605Smrg 573848b8605Smrg 574848b8605Smrg/* 575848b8605Smrg * Select an X visual which satisfies the RGBA/CI flag and minimum depth. 576848b8605Smrg * Input: dpy, screen - X display and screen number 577848b8605Smrg * min_depth - minimum visual depth 578848b8605Smrg * preferred_class - preferred GLX visual class or DONT_CARE 579848b8605Smrg * Return: pointer to an XVisualInfo or NULL. 580848b8605Smrg */ 581848b8605Smrgstatic XVisualInfo * 582848b8605Smrgchoose_x_visual(Display *dpy, int screen, int min_depth, int preferred_class) 583848b8605Smrg{ 584848b8605Smrg XVisualInfo *vis; 585848b8605Smrg int xclass, visclass = 0; 586848b8605Smrg int depth; 587848b8605Smrg 588848b8605Smrg /* First see if the MESA_RGB_VISUAL env var is defined */ 589848b8605Smrg vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" ); 590848b8605Smrg if (vis) { 591848b8605Smrg return vis; 592848b8605Smrg } 593848b8605Smrg /* Otherwise, search for a suitable visual */ 594848b8605Smrg if (preferred_class==DONT_CARE) { 595848b8605Smrg for (xclass=0;xclass<4;xclass++) { 596848b8605Smrg switch (xclass) { 597848b8605Smrg case 0: visclass = TrueColor; break; 598848b8605Smrg case 1: visclass = DirectColor; break; 599848b8605Smrg case 2: visclass = GrayScale; break; 600848b8605Smrg case 3: visclass = StaticGray; break; 601848b8605Smrg } 602848b8605Smrg if (min_depth==0) { 603848b8605Smrg /* start with shallowest */ 604848b8605Smrg for (depth=0;depth<=32;depth++) { 605848b8605Smrg vis = get_visual( dpy, screen, depth, visclass ); 606848b8605Smrg if (vis) { 607848b8605Smrg return vis; 608848b8605Smrg } 609848b8605Smrg } 610848b8605Smrg } 611848b8605Smrg else { 612848b8605Smrg /* start with deepest */ 613848b8605Smrg for (depth=32;depth>=min_depth;depth--) { 614848b8605Smrg vis = get_visual( dpy, screen, depth, visclass ); 615848b8605Smrg if (vis) { 616848b8605Smrg return vis; 617848b8605Smrg } 618848b8605Smrg } 619848b8605Smrg } 620848b8605Smrg } 621848b8605Smrg } 622848b8605Smrg else { 623848b8605Smrg /* search for a specific visual class */ 624848b8605Smrg switch (preferred_class) { 625848b8605Smrg case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; 626848b8605Smrg case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; 627848b8605Smrg case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; 628848b8605Smrg case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; 629848b8605Smrg case GLX_PSEUDO_COLOR_EXT: 630848b8605Smrg case GLX_STATIC_COLOR_EXT: 631848b8605Smrg default: return NULL; 632848b8605Smrg } 633848b8605Smrg if (min_depth==0) { 634848b8605Smrg /* start with shallowest */ 635848b8605Smrg for (depth=0;depth<=32;depth++) { 636848b8605Smrg vis = get_visual( dpy, screen, depth, visclass ); 637848b8605Smrg if (vis) { 638848b8605Smrg return vis; 639848b8605Smrg } 640848b8605Smrg } 641848b8605Smrg } 642848b8605Smrg else { 643848b8605Smrg /* start with deepest */ 644848b8605Smrg for (depth=32;depth>=min_depth;depth--) { 645848b8605Smrg vis = get_visual( dpy, screen, depth, visclass ); 646848b8605Smrg if (vis) { 647848b8605Smrg return vis; 648848b8605Smrg } 649848b8605Smrg } 650848b8605Smrg } 651848b8605Smrg } 652848b8605Smrg 653848b8605Smrg /* didn't find a visual */ 654848b8605Smrg return NULL; 655848b8605Smrg} 656848b8605Smrg 657848b8605Smrg 658848b8605Smrg 659848b8605Smrg/* 660848b8605Smrg * Find the deepest X over/underlay visual of at least min_depth. 661848b8605Smrg * Input: dpy, screen - X display and screen number 662848b8605Smrg * level - the over/underlay level 663848b8605Smrg * trans_type - transparent pixel type: GLX_NONE_EXT, 664848b8605Smrg * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT, 665848b8605Smrg * or DONT_CARE 666848b8605Smrg * trans_value - transparent pixel value or DONT_CARE 667848b8605Smrg * min_depth - minimum visual depth 668848b8605Smrg * preferred_class - preferred GLX visual class or DONT_CARE 669848b8605Smrg * Return: pointer to an XVisualInfo or NULL. 670848b8605Smrg */ 671848b8605Smrgstatic XVisualInfo * 672848b8605Smrgchoose_x_overlay_visual( Display *dpy, int scr, 673848b8605Smrg int level, int trans_type, int trans_value, 674848b8605Smrg int min_depth, int preferred_class ) 675848b8605Smrg{ 676848b8605Smrg OverlayInfo *overlay_info; 677848b8605Smrg int numOverlaysPerScreen; 678848b8605Smrg int i; 679848b8605Smrg XVisualInfo *deepvis; 680848b8605Smrg int deepest; 681848b8605Smrg 682848b8605Smrg /*DEBUG int tt, tv; */ 683848b8605Smrg 684848b8605Smrg switch (preferred_class) { 685848b8605Smrg case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break; 686848b8605Smrg case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break; 687848b8605Smrg case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break; 688848b8605Smrg case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break; 689848b8605Smrg case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break; 690848b8605Smrg case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break; 691848b8605Smrg default: preferred_class = DONT_CARE; 692848b8605Smrg } 693848b8605Smrg 694848b8605Smrg overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen); 695848b8605Smrg if (!overlay_info) { 696848b8605Smrg return NULL; 697848b8605Smrg } 698848b8605Smrg 699848b8605Smrg /* Search for the deepest overlay which satisifies all criteria. */ 700848b8605Smrg deepest = min_depth; 701848b8605Smrg deepvis = NULL; 702848b8605Smrg 703848b8605Smrg for (i = 0; i < numOverlaysPerScreen; i++) { 704848b8605Smrg const OverlayInfo *ov = overlay_info + i; 705848b8605Smrg XVisualInfo *vislist, vistemplate; 706848b8605Smrg int count; 707848b8605Smrg 708848b8605Smrg if (ov->layer!=level) { 709848b8605Smrg /* failed overlay level criteria */ 710848b8605Smrg continue; 711848b8605Smrg } 712848b8605Smrg if (!(trans_type==DONT_CARE 713848b8605Smrg || (trans_type==GLX_TRANSPARENT_INDEX_EXT 714848b8605Smrg && ov->transparent_type>0) 715848b8605Smrg || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) { 716848b8605Smrg /* failed transparent pixel type criteria */ 717848b8605Smrg continue; 718848b8605Smrg } 719848b8605Smrg if (trans_value!=DONT_CARE && trans_value!=ov->value) { 720848b8605Smrg /* failed transparent pixel value criteria */ 721848b8605Smrg continue; 722848b8605Smrg } 723848b8605Smrg 724848b8605Smrg /* get XVisualInfo and check the depth */ 725848b8605Smrg vistemplate.visualid = ov->overlay_visual; 726848b8605Smrg vistemplate.screen = scr; 727848b8605Smrg vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask, 728848b8605Smrg &vistemplate, &count ); 729848b8605Smrg 730b8e80941Smrg if (!vislist) { 731b8e80941Smrg /* no matches */ 732b8e80941Smrg continue; 733b8e80941Smrg } 734b8e80941Smrg 735848b8605Smrg if (count!=1) { 736848b8605Smrg /* something went wrong */ 737b8e80941Smrg free(vislist); 738848b8605Smrg continue; 739848b8605Smrg } 740848b8605Smrg if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) { 741848b8605Smrg /* wrong visual class */ 742b8e80941Smrg free(vislist); 743848b8605Smrg continue; 744848b8605Smrg } 745848b8605Smrg 746848b8605Smrg /* Color-index rendering is not supported. Make sure we have True/DirectColor */ 747b8e80941Smrg if (vislist->CLASS != TrueColor && vislist->CLASS != DirectColor) { 748b8e80941Smrg free(vislist); 749848b8605Smrg continue; 750b8e80941Smrg } 751848b8605Smrg 752b8e80941Smrg if (deepvis!=NULL && vislist->depth <= deepest) { 753b8e80941Smrg free(vislist); 754b8e80941Smrg continue; 755848b8605Smrg } 756b8e80941Smrg 757b8e80941Smrg /* YES! found a satisfactory visual */ 758b8e80941Smrg free(deepvis); 759b8e80941Smrg deepest = vislist->depth; 760b8e80941Smrg deepvis = vislist; 761b8e80941Smrg /* DEBUG tt = ov->transparent_type;*/ 762b8e80941Smrg /* DEBUG tv = ov->value; */ 763848b8605Smrg } 764848b8605Smrg 765848b8605Smrg/*DEBUG 766848b8605Smrg if (deepvis) { 767848b8605Smrg printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n", 768848b8605Smrg deepvis->visualid, level, deepvis->depth, tt, tv ); 769848b8605Smrg } 770848b8605Smrg*/ 771848b8605Smrg return deepvis; 772848b8605Smrg} 773848b8605Smrg 774848b8605Smrg 775848b8605Smrg/**********************************************************************/ 776848b8605Smrg/*** Display-related functions ***/ 777848b8605Smrg/**********************************************************************/ 778848b8605Smrg 779848b8605Smrg 780848b8605Smrg/** 781848b8605Smrg * Free all XMesaVisuals which are associated with the given display. 782848b8605Smrg */ 783848b8605Smrgstatic void 784848b8605Smrgdestroy_visuals_on_display(Display *dpy) 785848b8605Smrg{ 786848b8605Smrg int i; 787848b8605Smrg for (i = 0; i < NumVisuals; i++) { 788848b8605Smrg if (VisualTable[i]->display == dpy) { 789848b8605Smrg /* remove this visual */ 790848b8605Smrg int j; 791b8e80941Smrg XMesaDestroyVisual(VisualTable[i]); 792848b8605Smrg for (j = i; j < NumVisuals - 1; j++) 793848b8605Smrg VisualTable[j] = VisualTable[j + 1]; 794848b8605Smrg NumVisuals--; 795848b8605Smrg } 796848b8605Smrg } 797848b8605Smrg} 798848b8605Smrg 799848b8605Smrg 800848b8605Smrg/** 801848b8605Smrg * Called from XCloseDisplay() to let us free our display-related data. 802848b8605Smrg */ 803848b8605Smrgstatic int 804848b8605Smrgclose_display_callback(Display *dpy, XExtCodes *codes) 805848b8605Smrg{ 806848b8605Smrg destroy_visuals_on_display(dpy); 807848b8605Smrg xmesa_destroy_buffers_on_display(dpy); 808848b8605Smrg return 0; 809848b8605Smrg} 810848b8605Smrg 811848b8605Smrg 812848b8605Smrg/** 813848b8605Smrg * Look for the named extension on given display and return a pointer 814848b8605Smrg * to the _XExtension data, or NULL if extension not found. 815848b8605Smrg */ 816848b8605Smrgstatic _XExtension * 817848b8605Smrglookup_extension(Display *dpy, const char *extName) 818848b8605Smrg{ 819848b8605Smrg _XExtension *ext; 820848b8605Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 821848b8605Smrg if (ext->name && strcmp(ext->name, extName) == 0) { 822848b8605Smrg return ext; 823848b8605Smrg } 824848b8605Smrg } 825848b8605Smrg return NULL; 826848b8605Smrg} 827848b8605Smrg 828848b8605Smrg 829848b8605Smrg/** 830848b8605Smrg * Whenever we're given a new Display pointer, call this function to 831848b8605Smrg * register our close_display_callback function. 832848b8605Smrg */ 833848b8605Smrgstatic void 834848b8605Smrgregister_with_display(Display *dpy) 835848b8605Smrg{ 836848b8605Smrg const char *extName = "MesaGLX"; 837848b8605Smrg _XExtension *ext; 838848b8605Smrg 839848b8605Smrg ext = lookup_extension(dpy, extName); 840848b8605Smrg if (!ext) { 841848b8605Smrg XExtCodes *c = XAddExtension(dpy); 842848b8605Smrg ext = dpy->ext_procs; /* new extension is at head of list */ 843848b8605Smrg assert(c->extension == ext->codes.extension); 844848b8605Smrg (void) c; /* silence warning */ 845b8e80941Smrg ext->name = strdup(extName); 846848b8605Smrg ext->close_display = close_display_callback; 847848b8605Smrg } 848848b8605Smrg} 849848b8605Smrg 850848b8605Smrg 851848b8605Smrg/**********************************************************************/ 852848b8605Smrg/*** Begin Fake GLX API Functions ***/ 853848b8605Smrg/**********************************************************************/ 854848b8605Smrg 855848b8605Smrg 856848b8605Smrg/** 857848b8605Smrg * Helper used by glXChooseVisual and glXChooseFBConfig. 858848b8605Smrg * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for 859848b8605Smrg * the later. 860848b8605Smrg * In either case, the attribute list is terminated with the value 'None'. 861848b8605Smrg */ 862848b8605Smrgstatic XMesaVisual 863848b8605Smrgchoose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) 864848b8605Smrg{ 865848b8605Smrg const GLboolean rgbModeDefault = fbConfig; 866848b8605Smrg const int *parselist; 867848b8605Smrg XVisualInfo *vis; 868848b8605Smrg int min_ci = 0; 869848b8605Smrg int min_red=0, min_green=0, min_blue=0; 870848b8605Smrg GLboolean rgb_flag = rgbModeDefault; 871848b8605Smrg GLboolean alpha_flag = GL_FALSE; 872848b8605Smrg GLboolean double_flag = GL_FALSE; 873848b8605Smrg GLboolean stereo_flag = GL_FALSE; 874848b8605Smrg GLint depth_size = 0; 875848b8605Smrg GLint stencil_size = 0; 876848b8605Smrg GLint accumRedSize = 0; 877848b8605Smrg GLint accumGreenSize = 0; 878848b8605Smrg GLint accumBlueSize = 0; 879848b8605Smrg GLint accumAlphaSize = 0; 880848b8605Smrg int level = 0; 881848b8605Smrg int visual_type = DONT_CARE; 882848b8605Smrg int trans_type = DONT_CARE; 883848b8605Smrg int trans_value = DONT_CARE; 884848b8605Smrg GLint caveat = DONT_CARE; 885848b8605Smrg XMesaVisual xmvis = NULL; 886848b8605Smrg int desiredVisualID = -1; 887848b8605Smrg int numAux = 0; 888848b8605Smrg 889848b8605Smrg parselist = list; 890848b8605Smrg 891848b8605Smrg while (*parselist) { 892848b8605Smrg 893848b8605Smrg if (fbConfig && 894848b8605Smrg parselist[1] == GLX_DONT_CARE && 895848b8605Smrg parselist[0] != GLX_LEVEL) { 896848b8605Smrg /* For glXChooseFBConfig(), skip attributes whose value is 897848b8605Smrg * GLX_DONT_CARE (-1), unless it's GLX_LEVEL (which can legitimately be 898848b8605Smrg * a negative value). 899848b8605Smrg * 900848b8605Smrg * From page 17 (23 of the pdf) of the GLX 1.4 spec: 901848b8605Smrg * GLX DONT CARE may be specified for all attributes except GLX LEVEL. 902848b8605Smrg */ 903848b8605Smrg parselist += 2; 904848b8605Smrg continue; 905848b8605Smrg } 906848b8605Smrg 907848b8605Smrg switch (*parselist) { 908848b8605Smrg case GLX_USE_GL: 909848b8605Smrg if (fbConfig) { 910848b8605Smrg /* invalid token */ 911848b8605Smrg return NULL; 912848b8605Smrg } 913848b8605Smrg else { 914848b8605Smrg /* skip */ 915848b8605Smrg parselist++; 916848b8605Smrg } 917848b8605Smrg break; 918848b8605Smrg case GLX_BUFFER_SIZE: 919848b8605Smrg parselist++; 920848b8605Smrg min_ci = *parselist++; 921848b8605Smrg break; 922848b8605Smrg case GLX_LEVEL: 923848b8605Smrg parselist++; 924848b8605Smrg level = *parselist++; 925848b8605Smrg break; 926848b8605Smrg case GLX_RGBA: 927848b8605Smrg if (fbConfig) { 928848b8605Smrg /* invalid token */ 929848b8605Smrg return NULL; 930848b8605Smrg } 931848b8605Smrg else { 932848b8605Smrg rgb_flag = GL_TRUE; 933848b8605Smrg parselist++; 934848b8605Smrg } 935848b8605Smrg break; 936848b8605Smrg case GLX_DOUBLEBUFFER: 937848b8605Smrg parselist++; 938848b8605Smrg if (fbConfig) { 939848b8605Smrg double_flag = *parselist++; 940848b8605Smrg } 941848b8605Smrg else { 942848b8605Smrg double_flag = GL_TRUE; 943848b8605Smrg } 944848b8605Smrg break; 945848b8605Smrg case GLX_STEREO: 946848b8605Smrg parselist++; 947848b8605Smrg if (fbConfig) { 948848b8605Smrg stereo_flag = *parselist++; 949848b8605Smrg } 950848b8605Smrg else { 951848b8605Smrg stereo_flag = GL_TRUE; 952848b8605Smrg } 953848b8605Smrg break; 954848b8605Smrg case GLX_AUX_BUFFERS: 955848b8605Smrg parselist++; 956848b8605Smrg numAux = *parselist++; 957848b8605Smrg if (numAux > MAX_AUX_BUFFERS) 958848b8605Smrg return NULL; 959848b8605Smrg break; 960848b8605Smrg case GLX_RED_SIZE: 961848b8605Smrg parselist++; 962848b8605Smrg min_red = *parselist++; 963848b8605Smrg break; 964848b8605Smrg case GLX_GREEN_SIZE: 965848b8605Smrg parselist++; 966848b8605Smrg min_green = *parselist++; 967848b8605Smrg break; 968848b8605Smrg case GLX_BLUE_SIZE: 969848b8605Smrg parselist++; 970848b8605Smrg min_blue = *parselist++; 971848b8605Smrg break; 972848b8605Smrg case GLX_ALPHA_SIZE: 973848b8605Smrg parselist++; 974848b8605Smrg { 975848b8605Smrg GLint size = *parselist++; 976848b8605Smrg alpha_flag = size ? GL_TRUE : GL_FALSE; 977848b8605Smrg } 978848b8605Smrg break; 979848b8605Smrg case GLX_DEPTH_SIZE: 980848b8605Smrg parselist++; 981848b8605Smrg depth_size = *parselist++; 982848b8605Smrg break; 983848b8605Smrg case GLX_STENCIL_SIZE: 984848b8605Smrg parselist++; 985848b8605Smrg stencil_size = *parselist++; 986848b8605Smrg break; 987848b8605Smrg case GLX_ACCUM_RED_SIZE: 988848b8605Smrg parselist++; 989848b8605Smrg { 990848b8605Smrg GLint size = *parselist++; 991848b8605Smrg accumRedSize = MAX2( accumRedSize, size ); 992848b8605Smrg } 993848b8605Smrg break; 994848b8605Smrg case GLX_ACCUM_GREEN_SIZE: 995848b8605Smrg parselist++; 996848b8605Smrg { 997848b8605Smrg GLint size = *parselist++; 998848b8605Smrg accumGreenSize = MAX2( accumGreenSize, size ); 999848b8605Smrg } 1000848b8605Smrg break; 1001848b8605Smrg case GLX_ACCUM_BLUE_SIZE: 1002848b8605Smrg parselist++; 1003848b8605Smrg { 1004848b8605Smrg GLint size = *parselist++; 1005848b8605Smrg accumBlueSize = MAX2( accumBlueSize, size ); 1006848b8605Smrg } 1007848b8605Smrg break; 1008848b8605Smrg case GLX_ACCUM_ALPHA_SIZE: 1009848b8605Smrg parselist++; 1010848b8605Smrg { 1011848b8605Smrg GLint size = *parselist++; 1012848b8605Smrg accumAlphaSize = MAX2( accumAlphaSize, size ); 1013848b8605Smrg } 1014848b8605Smrg break; 1015848b8605Smrg 1016848b8605Smrg /* 1017848b8605Smrg * GLX_EXT_visual_info extension 1018848b8605Smrg */ 1019848b8605Smrg case GLX_X_VISUAL_TYPE_EXT: 1020848b8605Smrg parselist++; 1021848b8605Smrg visual_type = *parselist++; 1022848b8605Smrg break; 1023848b8605Smrg case GLX_TRANSPARENT_TYPE_EXT: 1024848b8605Smrg parselist++; 1025848b8605Smrg trans_type = *parselist++; 1026848b8605Smrg break; 1027848b8605Smrg case GLX_TRANSPARENT_INDEX_VALUE_EXT: 1028848b8605Smrg parselist++; 1029848b8605Smrg trans_value = *parselist++; 1030848b8605Smrg break; 1031848b8605Smrg case GLX_TRANSPARENT_RED_VALUE_EXT: 1032848b8605Smrg case GLX_TRANSPARENT_GREEN_VALUE_EXT: 1033848b8605Smrg case GLX_TRANSPARENT_BLUE_VALUE_EXT: 1034848b8605Smrg case GLX_TRANSPARENT_ALPHA_VALUE_EXT: 1035848b8605Smrg /* ignore */ 1036848b8605Smrg parselist++; 1037848b8605Smrg parselist++; 1038848b8605Smrg break; 1039848b8605Smrg 1040848b8605Smrg /* 1041848b8605Smrg * GLX_EXT_visual_info extension 1042848b8605Smrg */ 1043848b8605Smrg case GLX_VISUAL_CAVEAT_EXT: 1044848b8605Smrg parselist++; 1045848b8605Smrg caveat = *parselist++; /* ignored for now */ 1046848b8605Smrg break; 1047848b8605Smrg 1048848b8605Smrg /* 1049848b8605Smrg * GLX_ARB_multisample 1050848b8605Smrg */ 1051848b8605Smrg case GLX_SAMPLE_BUFFERS_ARB: 1052848b8605Smrg case GLX_SAMPLES_ARB: 1053848b8605Smrg parselist++; 1054848b8605Smrg if (*parselist++ != 0) 1055848b8605Smrg /* ms not supported */ 1056848b8605Smrg return NULL; 1057848b8605Smrg break; 1058848b8605Smrg 1059848b8605Smrg /* 1060848b8605Smrg * FBConfig attribs. 1061848b8605Smrg */ 1062848b8605Smrg case GLX_RENDER_TYPE: 1063848b8605Smrg if (!fbConfig) 1064848b8605Smrg return NULL; 1065848b8605Smrg parselist++; 1066848b8605Smrg if (*parselist & GLX_RGBA_BIT) { 1067848b8605Smrg rgb_flag = GL_TRUE; 1068848b8605Smrg } 1069848b8605Smrg else if (*parselist & GLX_COLOR_INDEX_BIT) { 1070848b8605Smrg rgb_flag = GL_FALSE; 1071848b8605Smrg } 1072848b8605Smrg else if (*parselist & (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) { 1073848b8605Smrg rgb_flag = GL_TRUE; 1074848b8605Smrg } 1075848b8605Smrg else if (*parselist == 0) { 1076848b8605Smrg rgb_flag = GL_TRUE; 1077848b8605Smrg } 1078848b8605Smrg parselist++; 1079848b8605Smrg break; 1080848b8605Smrg case GLX_DRAWABLE_TYPE: 1081848b8605Smrg if (!fbConfig) 1082848b8605Smrg return NULL; 1083848b8605Smrg parselist++; 1084848b8605Smrg if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { 1085848b8605Smrg return NULL; /* bad bit */ 1086848b8605Smrg } 1087848b8605Smrg parselist++; 1088848b8605Smrg break; 1089848b8605Smrg case GLX_FBCONFIG_ID: 1090848b8605Smrg case GLX_VISUAL_ID: 1091848b8605Smrg if (!fbConfig) 1092848b8605Smrg return NULL; 1093848b8605Smrg parselist++; 1094848b8605Smrg desiredVisualID = *parselist++; 1095848b8605Smrg break; 1096848b8605Smrg case GLX_X_RENDERABLE: 1097848b8605Smrg case GLX_MAX_PBUFFER_WIDTH: 1098848b8605Smrg case GLX_MAX_PBUFFER_HEIGHT: 1099848b8605Smrg case GLX_MAX_PBUFFER_PIXELS: 1100848b8605Smrg if (!fbConfig) 1101848b8605Smrg return NULL; 1102848b8605Smrg parselist += 2; 1103848b8605Smrg /* ignore */ 1104848b8605Smrg break; 1105848b8605Smrg 1106848b8605Smrg case GLX_BIND_TO_TEXTURE_RGB_EXT: 1107848b8605Smrg parselist++; /*skip*/ 1108848b8605Smrg break; 1109848b8605Smrg case GLX_BIND_TO_TEXTURE_RGBA_EXT: 1110848b8605Smrg parselist++; /*skip*/ 1111848b8605Smrg break; 1112848b8605Smrg case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 1113848b8605Smrg parselist++; /*skip*/ 1114848b8605Smrg break; 1115848b8605Smrg case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 1116848b8605Smrg parselist++; 1117848b8605Smrg if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | 1118848b8605Smrg GLX_TEXTURE_2D_BIT_EXT | 1119848b8605Smrg GLX_TEXTURE_RECTANGLE_BIT_EXT)) { 1120848b8605Smrg /* invalid bit */ 1121848b8605Smrg return NULL; 1122848b8605Smrg } 1123848b8605Smrg break; 1124848b8605Smrg case GLX_Y_INVERTED_EXT: 1125848b8605Smrg parselist++; /*skip*/ 1126848b8605Smrg break; 1127848b8605Smrg 1128848b8605Smrg case None: 1129848b8605Smrg /* end of list */ 1130848b8605Smrg break; 1131848b8605Smrg 1132848b8605Smrg default: 1133848b8605Smrg /* undefined attribute */ 1134848b8605Smrg _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", 1135848b8605Smrg *parselist); 1136848b8605Smrg return NULL; 1137848b8605Smrg } 1138848b8605Smrg } 1139848b8605Smrg 1140848b8605Smrg if (!rgb_flag) 1141848b8605Smrg return NULL; 1142848b8605Smrg 1143848b8605Smrg (void) caveat; 1144848b8605Smrg (void) min_ci; 1145848b8605Smrg 1146848b8605Smrg /* 1147848b8605Smrg * Since we're only simulating the GLX extension this function will never 1148848b8605Smrg * find any real GL visuals. Instead, all we can do is try to find an RGB 1149848b8605Smrg * or CI visual of appropriate depth. Other requested attributes such as 1150848b8605Smrg * double buffering, depth buffer, etc. will be associated with the X 1151848b8605Smrg * visual and stored in the VisualTable[]. 1152848b8605Smrg */ 1153848b8605Smrg if (desiredVisualID != -1) { 1154848b8605Smrg /* try to get a specific visual, by visualID */ 1155848b8605Smrg XVisualInfo temp; 1156848b8605Smrg int n; 1157848b8605Smrg temp.visualid = desiredVisualID; 1158848b8605Smrg temp.screen = screen; 1159848b8605Smrg vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); 1160848b8605Smrg if (vis) { 1161848b8605Smrg /* give the visual some useful GLX attributes */ 1162848b8605Smrg double_flag = GL_TRUE; 1163848b8605Smrg if (vis->depth <= 8) 1164848b8605Smrg return NULL; 1165848b8605Smrg depth_size = default_depth_bits(); 1166848b8605Smrg stencil_size = 8; 1167848b8605Smrg /* XXX accum??? */ 1168848b8605Smrg } 1169848b8605Smrg } 1170848b8605Smrg else { 1171848b8605Smrg /* RGB visual */ 1172848b8605Smrg int min_rgb = min_red + min_green + min_blue; 1173848b8605Smrg if (min_rgb>1 && min_rgb<8) { 1174848b8605Smrg /* a special case to be sure we can get a monochrome visual */ 1175848b8605Smrg min_rgb = 1; 1176848b8605Smrg } 1177848b8605Smrg 1178848b8605Smrg if (level==0) { 1179848b8605Smrg vis = choose_x_visual(dpy, screen, min_rgb, visual_type); 1180848b8605Smrg } 1181848b8605Smrg else { 1182848b8605Smrg vis = choose_x_overlay_visual(dpy, screen, level, 1183848b8605Smrg trans_type, trans_value, min_rgb, visual_type); 1184848b8605Smrg } 1185848b8605Smrg } 1186848b8605Smrg 1187848b8605Smrg if (vis) { 1188848b8605Smrg /* Note: we're not exactly obeying the glXChooseVisual rules here. 1189848b8605Smrg * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the 1190848b8605Smrg * largest depth buffer size, which is 32bits/value. Instead, we 1191848b8605Smrg * return 16 to maintain performance with earlier versions of Mesa. 1192848b8605Smrg */ 1193848b8605Smrg if (depth_size > 24) 1194848b8605Smrg depth_size = 32; 1195848b8605Smrg else if (depth_size > 16) 1196848b8605Smrg depth_size = 24; 1197848b8605Smrg else if (depth_size > 0) { 1198848b8605Smrg depth_size = default_depth_bits(); 1199848b8605Smrg } 1200848b8605Smrg 1201848b8605Smrg if (!alpha_flag) { 1202848b8605Smrg alpha_flag = default_alpha_bits() > 0; 1203848b8605Smrg } 1204848b8605Smrg 1205848b8605Smrg /* we only support one size of stencil and accum buffers. */ 1206848b8605Smrg if (stencil_size > 0) 1207848b8605Smrg stencil_size = 8; 1208848b8605Smrg if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || 1209848b8605Smrg accumAlphaSize > 0) { 1210848b8605Smrg accumRedSize = 1211848b8605Smrg accumGreenSize = 1212848b8605Smrg accumBlueSize = default_accum_bits(); 1213848b8605Smrg accumAlphaSize = alpha_flag ? accumRedSize : 0; 1214848b8605Smrg } 1215848b8605Smrg 1216848b8605Smrg xmvis = save_glx_visual( dpy, vis, alpha_flag, double_flag, 1217848b8605Smrg stereo_flag, depth_size, stencil_size, 1218848b8605Smrg accumRedSize, accumGreenSize, 1219848b8605Smrg accumBlueSize, accumAlphaSize, level, numAux ); 1220b8e80941Smrg free(vis); 1221848b8605Smrg } 1222848b8605Smrg 1223848b8605Smrg return xmvis; 1224848b8605Smrg} 1225848b8605Smrg 1226848b8605Smrg 1227848b8605Smrgstatic XVisualInfo * 1228848b8605SmrgFake_glXChooseVisual( Display *dpy, int screen, int *list ) 1229848b8605Smrg{ 1230848b8605Smrg XMesaVisual xmvis; 1231848b8605Smrg 1232848b8605Smrg /* register ourselves as an extension on this display */ 1233848b8605Smrg register_with_display(dpy); 1234848b8605Smrg 1235848b8605Smrg xmvis = choose_visual(dpy, screen, list, GL_FALSE); 1236848b8605Smrg if (xmvis) { 1237b8e80941Smrg XVisualInfo* visinfo = malloc(sizeof(XVisualInfo)); 1238b8e80941Smrg if (visinfo) { 1239b8e80941Smrg memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo)); 1240848b8605Smrg } 1241b8e80941Smrg return visinfo; 1242848b8605Smrg } 1243848b8605Smrg else 1244848b8605Smrg return NULL; 1245848b8605Smrg} 1246848b8605Smrg 1247848b8605Smrg 1248848b8605Smrgstatic GLXContext 1249848b8605SmrgFake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, 1250848b8605Smrg GLXContext share_list, Bool direct ) 1251848b8605Smrg{ 1252848b8605Smrg XMesaVisual xmvis; 1253848b8605Smrg XMesaContext xmesaCtx; 1254848b8605Smrg 1255848b8605Smrg if (!dpy || !visinfo) 1256848b8605Smrg return 0; 1257848b8605Smrg 1258848b8605Smrg /* deallocate unused windows/buffers */ 1259848b8605Smrg#if 0 1260848b8605Smrg XMesaGarbageCollect(dpy); 1261848b8605Smrg#endif 1262848b8605Smrg 1263848b8605Smrg xmvis = find_glx_visual( dpy, visinfo ); 1264848b8605Smrg if (!xmvis) { 1265848b8605Smrg /* This visual wasn't found with glXChooseVisual() */ 1266848b8605Smrg xmvis = create_glx_visual( dpy, visinfo ); 1267848b8605Smrg if (!xmvis) { 1268848b8605Smrg return NULL; 1269848b8605Smrg } 1270848b8605Smrg } 1271848b8605Smrg 1272848b8605Smrg xmesaCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list); 1273848b8605Smrg 1274848b8605Smrg return (GLXContext) xmesaCtx; 1275848b8605Smrg} 1276848b8605Smrg 1277848b8605Smrg 1278848b8605Smrg/* XXX these may have to be removed due to thread-safety issues. */ 1279848b8605Smrgstatic GLXContext MakeCurrent_PrevContext = 0; 1280848b8605Smrgstatic GLXDrawable MakeCurrent_PrevDrawable = 0; 1281848b8605Smrgstatic GLXDrawable MakeCurrent_PrevReadable = 0; 1282848b8605Smrgstatic XMesaBuffer MakeCurrent_PrevDrawBuffer = 0; 1283848b8605Smrgstatic XMesaBuffer MakeCurrent_PrevReadBuffer = 0; 1284848b8605Smrg 1285848b8605Smrg 1286848b8605Smrg/* GLX 1.3 and later */ 1287848b8605Smrgstatic Bool 1288848b8605SmrgFake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, 1289848b8605Smrg GLXDrawable read, GLXContext ctx ) 1290848b8605Smrg{ 1291848b8605Smrg if (ctx && draw && read) { 1292848b8605Smrg XMesaBuffer drawBuffer, readBuffer; 1293848b8605Smrg XMesaContext xmctx = (XMesaContext) ctx; 1294848b8605Smrg 1295848b8605Smrg /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ 1296848b8605Smrg if (ctx == MakeCurrent_PrevContext 1297848b8605Smrg && draw == MakeCurrent_PrevDrawable) { 1298848b8605Smrg drawBuffer = MakeCurrent_PrevDrawBuffer; 1299848b8605Smrg } 1300848b8605Smrg else { 1301848b8605Smrg drawBuffer = XMesaFindBuffer( dpy, draw ); 1302848b8605Smrg } 1303848b8605Smrg if (!drawBuffer) { 1304848b8605Smrg /* drawable must be a new window! */ 1305848b8605Smrg drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); 1306848b8605Smrg if (!drawBuffer) { 1307848b8605Smrg /* Out of memory, or context/drawable depth mismatch */ 1308848b8605Smrg return False; 1309848b8605Smrg } 1310848b8605Smrg } 1311848b8605Smrg 1312848b8605Smrg /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ 1313848b8605Smrg if (ctx == MakeCurrent_PrevContext 1314848b8605Smrg && read == MakeCurrent_PrevReadable) { 1315848b8605Smrg readBuffer = MakeCurrent_PrevReadBuffer; 1316848b8605Smrg } 1317848b8605Smrg else { 1318848b8605Smrg readBuffer = XMesaFindBuffer( dpy, read ); 1319848b8605Smrg } 1320848b8605Smrg if (!readBuffer) { 1321848b8605Smrg /* drawable must be a new window! */ 1322848b8605Smrg readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); 1323848b8605Smrg if (!readBuffer) { 1324848b8605Smrg /* Out of memory, or context/drawable depth mismatch */ 1325848b8605Smrg return False; 1326848b8605Smrg } 1327848b8605Smrg } 1328848b8605Smrg 1329848b8605Smrg MakeCurrent_PrevContext = ctx; 1330848b8605Smrg MakeCurrent_PrevDrawable = draw; 1331848b8605Smrg MakeCurrent_PrevReadable = read; 1332848b8605Smrg MakeCurrent_PrevDrawBuffer = drawBuffer; 1333848b8605Smrg MakeCurrent_PrevReadBuffer = readBuffer; 1334848b8605Smrg 1335848b8605Smrg /* Now make current! */ 1336848b8605Smrg return XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer); 1337848b8605Smrg } 1338848b8605Smrg else if (!ctx && !draw && !read) { 1339848b8605Smrg /* release current context w/out assigning new one. */ 1340848b8605Smrg XMesaMakeCurrent( NULL, NULL ); 1341848b8605Smrg MakeCurrent_PrevContext = 0; 1342848b8605Smrg MakeCurrent_PrevDrawable = 0; 1343848b8605Smrg MakeCurrent_PrevReadable = 0; 1344848b8605Smrg MakeCurrent_PrevDrawBuffer = 0; 1345848b8605Smrg MakeCurrent_PrevReadBuffer = 0; 1346848b8605Smrg return True; 1347848b8605Smrg } 1348848b8605Smrg else { 1349848b8605Smrg /* The args must either all be non-zero or all zero. 1350848b8605Smrg * This is an error. 1351848b8605Smrg */ 1352848b8605Smrg return False; 1353848b8605Smrg } 1354848b8605Smrg} 1355848b8605Smrg 1356848b8605Smrg 1357848b8605Smrgstatic Bool 1358848b8605SmrgFake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) 1359848b8605Smrg{ 1360848b8605Smrg return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx ); 1361848b8605Smrg} 1362848b8605Smrg 1363848b8605Smrg 1364848b8605Smrgstatic GLXPixmap 1365848b8605SmrgFake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) 1366848b8605Smrg{ 1367848b8605Smrg XMesaVisual v; 1368848b8605Smrg XMesaBuffer b; 1369848b8605Smrg 1370848b8605Smrg v = find_glx_visual( dpy, visinfo ); 1371848b8605Smrg if (!v) { 1372848b8605Smrg v = create_glx_visual( dpy, visinfo ); 1373848b8605Smrg if (!v) { 1374848b8605Smrg /* unusable visual */ 1375848b8605Smrg return 0; 1376848b8605Smrg } 1377848b8605Smrg } 1378848b8605Smrg 1379848b8605Smrg b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); 1380848b8605Smrg if (!b) { 1381848b8605Smrg return 0; 1382848b8605Smrg } 1383848b8605Smrg return b->frontxrb->pixmap; 1384848b8605Smrg} 1385848b8605Smrg 1386848b8605Smrg 1387848b8605Smrg/*** GLX_MESA_pixmap_colormap ***/ 1388848b8605Smrg 1389848b8605Smrgstatic GLXPixmap 1390848b8605SmrgFake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, 1391848b8605Smrg Pixmap pixmap, Colormap cmap ) 1392848b8605Smrg{ 1393848b8605Smrg XMesaVisual v; 1394848b8605Smrg XMesaBuffer b; 1395848b8605Smrg 1396848b8605Smrg v = find_glx_visual( dpy, visinfo ); 1397848b8605Smrg if (!v) { 1398848b8605Smrg v = create_glx_visual( dpy, visinfo ); 1399848b8605Smrg if (!v) { 1400848b8605Smrg /* unusable visual */ 1401848b8605Smrg return 0; 1402848b8605Smrg } 1403848b8605Smrg } 1404848b8605Smrg 1405848b8605Smrg b = XMesaCreatePixmapBuffer( v, pixmap, cmap ); 1406848b8605Smrg if (!b) { 1407848b8605Smrg return 0; 1408848b8605Smrg } 1409848b8605Smrg return b->frontxrb->pixmap; 1410848b8605Smrg} 1411848b8605Smrg 1412848b8605Smrg 1413848b8605Smrgstatic void 1414848b8605SmrgFake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) 1415848b8605Smrg{ 1416848b8605Smrg XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); 1417848b8605Smrg if (b) { 1418848b8605Smrg XMesaDestroyBuffer(b); 1419848b8605Smrg } 1420b8e80941Smrg else if (getenv("MESA_DEBUG")) { 1421848b8605Smrg _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); 1422848b8605Smrg } 1423848b8605Smrg} 1424848b8605Smrg 1425848b8605Smrg 1426848b8605Smrgstatic void 1427848b8605SmrgFake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, 1428848b8605Smrg unsigned long mask ) 1429848b8605Smrg{ 1430848b8605Smrg XMesaContext xmSrc = (XMesaContext) src; 1431848b8605Smrg XMesaContext xmDst = (XMesaContext) dst; 1432848b8605Smrg (void) dpy; 1433848b8605Smrg if (MakeCurrent_PrevContext == src) { 1434848b8605Smrg _mesa_Flush(); 1435848b8605Smrg } 1436848b8605Smrg _mesa_copy_context( &xmSrc->mesa, &xmDst->mesa, (GLuint) mask ); 1437848b8605Smrg} 1438848b8605Smrg 1439848b8605Smrg 1440848b8605Smrgstatic Bool 1441848b8605SmrgFake_glXQueryExtension( Display *dpy, int *errorBase, int *eventBase ) 1442848b8605Smrg{ 1443848b8605Smrg int op, ev, err; 1444848b8605Smrg /* Mesa's GLX isn't really an X extension but we try to act like one. */ 1445848b8605Smrg if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err)) 1446848b8605Smrg ev = err = 0; 1447848b8605Smrg if (errorBase) 1448848b8605Smrg *errorBase = err; 1449848b8605Smrg if (eventBase) 1450848b8605Smrg *eventBase = ev; 1451848b8605Smrg return True; /* we're faking GLX so always return success */ 1452848b8605Smrg} 1453848b8605Smrg 1454848b8605Smrg 1455848b8605Smrgextern void _kw_ungrab_all( Display *dpy ); 1456848b8605Smrgvoid _kw_ungrab_all( Display *dpy ) 1457848b8605Smrg{ 1458848b8605Smrg XUngrabPointer( dpy, CurrentTime ); 1459848b8605Smrg XUngrabKeyboard( dpy, CurrentTime ); 1460848b8605Smrg} 1461848b8605Smrg 1462848b8605Smrg 1463848b8605Smrgstatic void 1464848b8605SmrgFake_glXDestroyContext( Display *dpy, GLXContext ctx ) 1465848b8605Smrg{ 1466848b8605Smrg if (ctx) { 1467848b8605Smrg (void) dpy; 1468848b8605Smrg MakeCurrent_PrevContext = 0; 1469848b8605Smrg MakeCurrent_PrevDrawable = 0; 1470848b8605Smrg MakeCurrent_PrevReadable = 0; 1471848b8605Smrg MakeCurrent_PrevDrawBuffer = 0; 1472848b8605Smrg MakeCurrent_PrevReadBuffer = 0; 1473848b8605Smrg XMesaDestroyContext((XMesaContext) ctx); 1474848b8605Smrg XMesaGarbageCollect(dpy); 1475848b8605Smrg } 1476848b8605Smrg} 1477848b8605Smrg 1478848b8605Smrg 1479848b8605Smrgstatic Bool 1480848b8605SmrgFake_glXIsDirect( Display *dpy, GLXContext ctx ) 1481848b8605Smrg{ 1482848b8605Smrg XMesaContext xmCtx = (XMesaContext) ctx; 1483848b8605Smrg return xmCtx ? xmCtx->direct : False; 1484848b8605Smrg} 1485848b8605Smrg 1486848b8605Smrg 1487848b8605Smrg 1488848b8605Smrgstatic void 1489848b8605SmrgFake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) 1490848b8605Smrg{ 1491848b8605Smrg XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); 1492848b8605Smrg 1493848b8605Smrg if (buffer) { 1494848b8605Smrg XMesaSwapBuffers(buffer); 1495848b8605Smrg } 1496b8e80941Smrg else if (getenv("MESA_DEBUG")) { 1497848b8605Smrg _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", 1498848b8605Smrg (int) drawable); 1499848b8605Smrg } 1500848b8605Smrg} 1501848b8605Smrg 1502848b8605Smrg 1503848b8605Smrg 1504848b8605Smrg/*** GLX_MESA_copy_sub_buffer ***/ 1505848b8605Smrg 1506848b8605Smrgstatic void 1507848b8605SmrgFake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, 1508848b8605Smrg int x, int y, int width, int height ) 1509848b8605Smrg{ 1510848b8605Smrg XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); 1511848b8605Smrg if (buffer) { 1512848b8605Smrg XMesaCopySubBuffer(buffer, x, y, width, height); 1513848b8605Smrg } 1514b8e80941Smrg else if (getenv("MESA_DEBUG")) { 1515848b8605Smrg _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); 1516848b8605Smrg } 1517848b8605Smrg} 1518848b8605Smrg 1519848b8605Smrg 1520848b8605Smrgstatic Bool 1521848b8605SmrgFake_glXQueryVersion( Display *dpy, int *maj, int *min ) 1522848b8605Smrg{ 1523848b8605Smrg (void) dpy; 1524848b8605Smrg /* Return GLX version, not Mesa version */ 1525848b8605Smrg assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION); 1526848b8605Smrg *maj = CLIENT_MAJOR_VERSION; 1527848b8605Smrg *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION ); 1528848b8605Smrg return True; 1529848b8605Smrg} 1530848b8605Smrg 1531848b8605Smrg 1532848b8605Smrg/* 1533848b8605Smrg * Query the GLX attributes of the given XVisualInfo. 1534848b8605Smrg */ 1535848b8605Smrgstatic int 1536848b8605Smrgget_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) 1537848b8605Smrg{ 1538b8e80941Smrg assert(xmvis); 1539848b8605Smrg switch(attrib) { 1540848b8605Smrg case GLX_USE_GL: 1541848b8605Smrg if (fbconfig) 1542848b8605Smrg return GLX_BAD_ATTRIBUTE; 1543848b8605Smrg *value = (int) True; 1544848b8605Smrg return 0; 1545848b8605Smrg case GLX_BUFFER_SIZE: 1546848b8605Smrg *value = xmvis->visinfo->depth; 1547848b8605Smrg return 0; 1548848b8605Smrg case GLX_LEVEL: 1549848b8605Smrg *value = xmvis->mesa_visual.level; 1550848b8605Smrg return 0; 1551848b8605Smrg case GLX_RGBA: 1552848b8605Smrg if (fbconfig) 1553848b8605Smrg return GLX_BAD_ATTRIBUTE; 1554848b8605Smrg if (xmvis->mesa_visual.rgbMode) { 1555848b8605Smrg *value = True; 1556848b8605Smrg } 1557848b8605Smrg else { 1558848b8605Smrg *value = False; 1559848b8605Smrg } 1560848b8605Smrg return 0; 1561848b8605Smrg case GLX_DOUBLEBUFFER: 1562848b8605Smrg *value = (int) xmvis->mesa_visual.doubleBufferMode; 1563848b8605Smrg return 0; 1564848b8605Smrg case GLX_STEREO: 1565848b8605Smrg *value = (int) xmvis->mesa_visual.stereoMode; 1566848b8605Smrg return 0; 1567848b8605Smrg case GLX_AUX_BUFFERS: 1568848b8605Smrg *value = xmvis->mesa_visual.numAuxBuffers; 1569848b8605Smrg return 0; 1570848b8605Smrg case GLX_RED_SIZE: 1571848b8605Smrg *value = xmvis->mesa_visual.redBits; 1572848b8605Smrg return 0; 1573848b8605Smrg case GLX_GREEN_SIZE: 1574848b8605Smrg *value = xmvis->mesa_visual.greenBits; 1575848b8605Smrg return 0; 1576848b8605Smrg case GLX_BLUE_SIZE: 1577848b8605Smrg *value = xmvis->mesa_visual.blueBits; 1578848b8605Smrg return 0; 1579848b8605Smrg case GLX_ALPHA_SIZE: 1580848b8605Smrg *value = xmvis->mesa_visual.alphaBits; 1581848b8605Smrg return 0; 1582848b8605Smrg case GLX_DEPTH_SIZE: 1583848b8605Smrg *value = xmvis->mesa_visual.depthBits; 1584848b8605Smrg return 0; 1585848b8605Smrg case GLX_STENCIL_SIZE: 1586848b8605Smrg *value = xmvis->mesa_visual.stencilBits; 1587848b8605Smrg return 0; 1588848b8605Smrg case GLX_ACCUM_RED_SIZE: 1589848b8605Smrg *value = xmvis->mesa_visual.accumRedBits; 1590848b8605Smrg return 0; 1591848b8605Smrg case GLX_ACCUM_GREEN_SIZE: 1592848b8605Smrg *value = xmvis->mesa_visual.accumGreenBits; 1593848b8605Smrg return 0; 1594848b8605Smrg case GLX_ACCUM_BLUE_SIZE: 1595848b8605Smrg *value = xmvis->mesa_visual.accumBlueBits; 1596848b8605Smrg return 0; 1597848b8605Smrg case GLX_ACCUM_ALPHA_SIZE: 1598848b8605Smrg *value = xmvis->mesa_visual.accumAlphaBits; 1599848b8605Smrg return 0; 1600848b8605Smrg 1601848b8605Smrg /* 1602848b8605Smrg * GLX_EXT_visual_info extension 1603848b8605Smrg */ 1604848b8605Smrg case GLX_X_VISUAL_TYPE_EXT: 1605848b8605Smrg switch (xmvis->visinfo->CLASS) { 1606848b8605Smrg case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0; 1607848b8605Smrg case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0; 1608848b8605Smrg case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0; 1609848b8605Smrg case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0; 1610848b8605Smrg case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0; 1611848b8605Smrg case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0; 1612848b8605Smrg } 1613848b8605Smrg return 0; 1614848b8605Smrg case GLX_TRANSPARENT_TYPE_EXT: 1615848b8605Smrg if (xmvis->mesa_visual.level==0) { 1616848b8605Smrg /* normal planes */ 1617848b8605Smrg *value = GLX_NONE_EXT; 1618848b8605Smrg } 1619848b8605Smrg else if (xmvis->mesa_visual.level>0) { 1620848b8605Smrg /* overlay */ 1621848b8605Smrg if (xmvis->mesa_visual.rgbMode) { 1622848b8605Smrg *value = GLX_TRANSPARENT_RGB_EXT; 1623848b8605Smrg } 1624848b8605Smrg else { 1625848b8605Smrg *value = GLX_TRANSPARENT_INDEX_EXT; 1626848b8605Smrg } 1627848b8605Smrg } 1628848b8605Smrg else if (xmvis->mesa_visual.level<0) { 1629848b8605Smrg /* underlay */ 1630848b8605Smrg *value = GLX_NONE_EXT; 1631848b8605Smrg } 1632848b8605Smrg return 0; 1633848b8605Smrg case GLX_TRANSPARENT_INDEX_VALUE_EXT: 1634848b8605Smrg { 1635848b8605Smrg int pixel = transparent_pixel( xmvis ); 1636848b8605Smrg if (pixel>=0) { 1637848b8605Smrg *value = pixel; 1638848b8605Smrg } 1639848b8605Smrg /* else undefined */ 1640848b8605Smrg } 1641848b8605Smrg return 0; 1642848b8605Smrg case GLX_TRANSPARENT_RED_VALUE_EXT: 1643848b8605Smrg /* undefined */ 1644848b8605Smrg return 0; 1645848b8605Smrg case GLX_TRANSPARENT_GREEN_VALUE_EXT: 1646848b8605Smrg /* undefined */ 1647848b8605Smrg return 0; 1648848b8605Smrg case GLX_TRANSPARENT_BLUE_VALUE_EXT: 1649848b8605Smrg /* undefined */ 1650848b8605Smrg return 0; 1651848b8605Smrg case GLX_TRANSPARENT_ALPHA_VALUE_EXT: 1652848b8605Smrg /* undefined */ 1653848b8605Smrg return 0; 1654848b8605Smrg 1655848b8605Smrg /* 1656848b8605Smrg * GLX_EXT_visual_info extension 1657848b8605Smrg */ 1658848b8605Smrg case GLX_VISUAL_CAVEAT_EXT: 1659848b8605Smrg /* test for zero, just in case */ 1660848b8605Smrg if (xmvis->mesa_visual.visualRating > 0) 1661848b8605Smrg *value = xmvis->mesa_visual.visualRating; 1662848b8605Smrg else 1663848b8605Smrg *value = GLX_NONE_EXT; 1664848b8605Smrg return 0; 1665848b8605Smrg 1666848b8605Smrg /* 1667848b8605Smrg * GLX_ARB_multisample 1668848b8605Smrg */ 1669848b8605Smrg case GLX_SAMPLE_BUFFERS_ARB: 1670848b8605Smrg *value = 0; 1671848b8605Smrg return 0; 1672848b8605Smrg case GLX_SAMPLES_ARB: 1673848b8605Smrg *value = 0; 1674848b8605Smrg return 0; 1675848b8605Smrg 1676848b8605Smrg /* 1677848b8605Smrg * For FBConfigs: 1678848b8605Smrg */ 1679848b8605Smrg case GLX_SCREEN_EXT: 1680848b8605Smrg if (!fbconfig) 1681848b8605Smrg return GLX_BAD_ATTRIBUTE; 1682848b8605Smrg *value = xmvis->visinfo->screen; 1683848b8605Smrg break; 1684848b8605Smrg case GLX_DRAWABLE_TYPE: /*SGIX too */ 1685848b8605Smrg if (!fbconfig) 1686848b8605Smrg return GLX_BAD_ATTRIBUTE; 1687848b8605Smrg *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; 1688848b8605Smrg break; 1689848b8605Smrg case GLX_RENDER_TYPE_SGIX: 1690848b8605Smrg if (!fbconfig) 1691848b8605Smrg return GLX_BAD_ATTRIBUTE; 1692848b8605Smrg if (xmvis->mesa_visual.floatMode) 1693848b8605Smrg *value = GLX_RGBA_FLOAT_BIT_ARB; 1694848b8605Smrg else if (xmvis->mesa_visual.rgbMode) 1695848b8605Smrg *value = GLX_RGBA_BIT; 1696848b8605Smrg else 1697848b8605Smrg *value = GLX_COLOR_INDEX_BIT; 1698848b8605Smrg break; 1699848b8605Smrg case GLX_X_RENDERABLE_SGIX: 1700848b8605Smrg if (!fbconfig) 1701848b8605Smrg return GLX_BAD_ATTRIBUTE; 1702848b8605Smrg *value = True; /* XXX really? */ 1703848b8605Smrg break; 1704848b8605Smrg case GLX_FBCONFIG_ID_SGIX: 1705848b8605Smrg if (!fbconfig) 1706848b8605Smrg return GLX_BAD_ATTRIBUTE; 1707848b8605Smrg *value = xmvis->visinfo->visualid; 1708848b8605Smrg break; 1709848b8605Smrg case GLX_MAX_PBUFFER_WIDTH: 1710848b8605Smrg if (!fbconfig) 1711848b8605Smrg return GLX_BAD_ATTRIBUTE; 1712b8e80941Smrg /* XXX should be same as ctx->Const.MaxRenderbufferSize */ 1713848b8605Smrg *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); 1714848b8605Smrg break; 1715848b8605Smrg case GLX_MAX_PBUFFER_HEIGHT: 1716848b8605Smrg if (!fbconfig) 1717848b8605Smrg return GLX_BAD_ATTRIBUTE; 1718848b8605Smrg *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen); 1719848b8605Smrg break; 1720848b8605Smrg case GLX_MAX_PBUFFER_PIXELS: 1721848b8605Smrg if (!fbconfig) 1722848b8605Smrg return GLX_BAD_ATTRIBUTE; 1723848b8605Smrg *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) * 1724848b8605Smrg DisplayHeight(xmvis->display, xmvis->visinfo->screen); 1725848b8605Smrg break; 1726848b8605Smrg case GLX_VISUAL_ID: 1727848b8605Smrg if (!fbconfig) 1728848b8605Smrg return GLX_BAD_ATTRIBUTE; 1729848b8605Smrg *value = xmvis->visinfo->visualid; 1730848b8605Smrg break; 1731848b8605Smrg 1732848b8605Smrg case GLX_BIND_TO_TEXTURE_RGB_EXT: 1733848b8605Smrg *value = True; /*XXX*/ 1734848b8605Smrg break; 1735848b8605Smrg case GLX_BIND_TO_TEXTURE_RGBA_EXT: 1736848b8605Smrg /* XXX review */ 1737848b8605Smrg *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; 1738848b8605Smrg break; 1739848b8605Smrg case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 1740848b8605Smrg *value = True; /*XXX*/ 1741848b8605Smrg break; 1742848b8605Smrg case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 1743848b8605Smrg *value = (GLX_TEXTURE_1D_BIT_EXT | 1744848b8605Smrg GLX_TEXTURE_2D_BIT_EXT | 1745848b8605Smrg GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ 1746848b8605Smrg break; 1747848b8605Smrg case GLX_Y_INVERTED_EXT: 1748848b8605Smrg *value = True; /*XXX*/ 1749848b8605Smrg break; 1750848b8605Smrg 1751848b8605Smrg default: 1752848b8605Smrg return GLX_BAD_ATTRIBUTE; 1753848b8605Smrg } 1754848b8605Smrg return Success; 1755848b8605Smrg} 1756848b8605Smrg 1757848b8605Smrg 1758848b8605Smrgstatic int 1759848b8605SmrgFake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, 1760848b8605Smrg int attrib, int *value ) 1761848b8605Smrg{ 1762848b8605Smrg XMesaVisual xmvis; 1763848b8605Smrg int k; 1764848b8605Smrg if (!dpy || !visinfo) 1765848b8605Smrg return GLX_BAD_ATTRIBUTE; 1766848b8605Smrg 1767848b8605Smrg xmvis = find_glx_visual( dpy, visinfo ); 1768848b8605Smrg if (!xmvis) { 1769848b8605Smrg /* this visual wasn't obtained with glXChooseVisual */ 1770848b8605Smrg xmvis = create_glx_visual( dpy, visinfo ); 1771848b8605Smrg if (!xmvis) { 1772848b8605Smrg /* this visual can't be used for GL rendering */ 1773848b8605Smrg if (attrib==GLX_USE_GL) { 1774848b8605Smrg *value = (int) False; 1775848b8605Smrg return 0; 1776848b8605Smrg } 1777848b8605Smrg else { 1778848b8605Smrg return GLX_BAD_VISUAL; 1779848b8605Smrg } 1780848b8605Smrg } 1781848b8605Smrg } 1782848b8605Smrg 1783848b8605Smrg k = get_config(xmvis, attrib, value, GL_FALSE); 1784848b8605Smrg return k; 1785848b8605Smrg} 1786848b8605Smrg 1787848b8605Smrg 1788848b8605Smrgstatic GLXContext 1789848b8605SmrgFake_glXGetCurrentContext(void) 1790848b8605Smrg{ 1791848b8605Smrg XMesaContext xmesa = XMesaGetCurrentContext(); 1792848b8605Smrg return (GLXContext) xmesa; 1793848b8605Smrg} 1794848b8605Smrg 1795848b8605Smrgstatic void 1796848b8605SmrgFake_glXWaitGL( void ) 1797848b8605Smrg{ 1798848b8605Smrg XMesaContext xmesa = XMesaGetCurrentContext(); 1799848b8605Smrg XMesaFlush( xmesa ); 1800848b8605Smrg} 1801848b8605Smrg 1802848b8605Smrg 1803848b8605Smrg 1804848b8605Smrgstatic void 1805848b8605SmrgFake_glXWaitX( void ) 1806848b8605Smrg{ 1807848b8605Smrg XMesaContext xmesa = XMesaGetCurrentContext(); 1808848b8605Smrg XMesaFlush( xmesa ); 1809848b8605Smrg} 1810848b8605Smrg 1811848b8605Smrg 1812848b8605Smrgstatic const char * 1813848b8605Smrgget_extensions( void ) 1814848b8605Smrg{ 1815848b8605Smrg return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */ 1816848b8605Smrg} 1817848b8605Smrg 1818848b8605Smrg 1819848b8605Smrg 1820848b8605Smrg/* GLX 1.1 and later */ 1821848b8605Smrgstatic const char * 1822848b8605SmrgFake_glXQueryExtensionsString( Display *dpy, int screen ) 1823848b8605Smrg{ 1824848b8605Smrg (void) dpy; 1825848b8605Smrg (void) screen; 1826848b8605Smrg return get_extensions(); 1827848b8605Smrg} 1828848b8605Smrg 1829848b8605Smrg 1830848b8605Smrg 1831848b8605Smrg/* GLX 1.1 and later */ 1832848b8605Smrgstatic const char * 1833848b8605SmrgFake_glXQueryServerString( Display *dpy, int screen, int name ) 1834848b8605Smrg{ 1835848b8605Smrg static char version[1000]; 1836848b8605Smrg sprintf(version, "%d.%d %s", 1837848b8605Smrg SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); 1838848b8605Smrg 1839848b8605Smrg (void) dpy; 1840848b8605Smrg (void) screen; 1841848b8605Smrg 1842848b8605Smrg switch (name) { 1843848b8605Smrg case GLX_EXTENSIONS: 1844848b8605Smrg return get_extensions(); 1845848b8605Smrg case GLX_VENDOR: 1846848b8605Smrg return VENDOR; 1847848b8605Smrg case GLX_VERSION: 1848848b8605Smrg return version; 1849848b8605Smrg default: 1850848b8605Smrg return NULL; 1851848b8605Smrg } 1852848b8605Smrg} 1853848b8605Smrg 1854848b8605Smrg 1855848b8605Smrg 1856848b8605Smrg/* GLX 1.1 and later */ 1857848b8605Smrgstatic const char * 1858848b8605SmrgFake_glXGetClientString( Display *dpy, int name ) 1859848b8605Smrg{ 1860848b8605Smrg static char version[1000]; 1861848b8605Smrg sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, 1862848b8605Smrg CLIENT_MINOR_VERSION, MESA_GLX_VERSION); 1863848b8605Smrg 1864848b8605Smrg (void) dpy; 1865848b8605Smrg 1866848b8605Smrg switch (name) { 1867848b8605Smrg case GLX_EXTENSIONS: 1868848b8605Smrg return get_extensions(); 1869848b8605Smrg case GLX_VENDOR: 1870848b8605Smrg return VENDOR; 1871848b8605Smrg case GLX_VERSION: 1872848b8605Smrg return version; 1873848b8605Smrg default: 1874848b8605Smrg return NULL; 1875848b8605Smrg } 1876848b8605Smrg} 1877848b8605Smrg 1878848b8605Smrg 1879848b8605Smrg 1880848b8605Smrg/* 1881848b8605Smrg * GLX 1.3 and later 1882848b8605Smrg */ 1883848b8605Smrg 1884848b8605Smrg 1885848b8605Smrgstatic int 1886848b8605SmrgFake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, 1887848b8605Smrg int attribute, int *value ) 1888848b8605Smrg{ 1889848b8605Smrg XMesaVisual v = (XMesaVisual) config; 1890848b8605Smrg (void) dpy; 1891848b8605Smrg (void) config; 1892848b8605Smrg 1893848b8605Smrg if (!dpy || !config || !value) 1894848b8605Smrg return -1; 1895848b8605Smrg 1896848b8605Smrg return get_config(v, attribute, value, GL_TRUE); 1897848b8605Smrg} 1898848b8605Smrg 1899848b8605Smrg 1900848b8605Smrgstatic GLXFBConfig * 1901848b8605SmrgFake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) 1902848b8605Smrg{ 1903848b8605Smrg XVisualInfo *visuals, visTemplate; 1904848b8605Smrg const long visMask = VisualScreenMask; 1905848b8605Smrg int i; 1906848b8605Smrg 1907848b8605Smrg /* Get list of all X visuals */ 1908848b8605Smrg visTemplate.screen = screen; 1909848b8605Smrg visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); 1910848b8605Smrg if (*nelements > 0) { 1911848b8605Smrg XMesaVisual *results; 1912848b8605Smrg results = malloc(*nelements * sizeof(XMesaVisual)); 1913848b8605Smrg if (!results) { 1914848b8605Smrg *nelements = 0; 1915848b8605Smrg return NULL; 1916848b8605Smrg } 1917848b8605Smrg for (i = 0; i < *nelements; i++) { 1918848b8605Smrg results[i] = create_glx_visual(dpy, visuals + i); 1919848b8605Smrg } 1920b8e80941Smrg free(visuals); 1921848b8605Smrg return (GLXFBConfig *) results; 1922848b8605Smrg } 1923848b8605Smrg return NULL; 1924848b8605Smrg} 1925848b8605Smrg 1926848b8605Smrg 1927848b8605Smrgstatic GLXFBConfig * 1928848b8605SmrgFake_glXChooseFBConfig( Display *dpy, int screen, 1929848b8605Smrg const int *attribList, int *nitems ) 1930848b8605Smrg{ 1931848b8605Smrg XMesaVisual xmvis; 1932848b8605Smrg 1933848b8605Smrg /* register ourselves as an extension on this display */ 1934848b8605Smrg register_with_display(dpy); 1935848b8605Smrg 1936848b8605Smrg if (!attribList || !attribList[0]) { 1937848b8605Smrg /* return list of all configs (per GLX_SGIX_fbconfig spec) */ 1938848b8605Smrg return Fake_glXGetFBConfigs(dpy, screen, nitems); 1939848b8605Smrg } 1940848b8605Smrg 1941848b8605Smrg xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); 1942848b8605Smrg if (xmvis) { 1943848b8605Smrg GLXFBConfig *config = malloc(sizeof(XMesaVisual)); 1944848b8605Smrg if (!config) { 1945848b8605Smrg *nitems = 0; 1946848b8605Smrg return NULL; 1947848b8605Smrg } 1948848b8605Smrg *nitems = 1; 1949848b8605Smrg config[0] = (GLXFBConfig) xmvis; 1950848b8605Smrg return (GLXFBConfig *) config; 1951848b8605Smrg } 1952848b8605Smrg else { 1953848b8605Smrg *nitems = 0; 1954848b8605Smrg return NULL; 1955848b8605Smrg } 1956848b8605Smrg} 1957848b8605Smrg 1958848b8605Smrg 1959848b8605Smrgstatic XVisualInfo * 1960848b8605SmrgFake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) 1961848b8605Smrg{ 1962848b8605Smrg if (dpy && config) { 1963848b8605Smrg XMesaVisual xmvis = (XMesaVisual) config; 1964b8e80941Smrg XVisualInfo* visinfo = malloc(sizeof(XVisualInfo)); 1965b8e80941Smrg if (visinfo) { 1966b8e80941Smrg memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo)); 1967848b8605Smrg } 1968b8e80941Smrg return visinfo; 1969848b8605Smrg } 1970848b8605Smrg else { 1971848b8605Smrg return NULL; 1972848b8605Smrg } 1973848b8605Smrg} 1974848b8605Smrg 1975848b8605Smrg 1976848b8605Smrgstatic GLXWindow 1977848b8605SmrgFake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, 1978848b8605Smrg const int *attribList ) 1979848b8605Smrg{ 1980848b8605Smrg XMesaVisual xmvis = (XMesaVisual) config; 1981848b8605Smrg XMesaBuffer xmbuf; 1982848b8605Smrg if (!xmvis) 1983848b8605Smrg return 0; 1984848b8605Smrg 1985848b8605Smrg xmbuf = XMesaCreateWindowBuffer(xmvis, win); 1986848b8605Smrg if (!xmbuf) 1987848b8605Smrg return 0; 1988848b8605Smrg 1989848b8605Smrg (void) dpy; 1990848b8605Smrg (void) attribList; /* Ignored in GLX 1.3 */ 1991848b8605Smrg 1992848b8605Smrg return win; /* A hack for now */ 1993848b8605Smrg} 1994848b8605Smrg 1995848b8605Smrg 1996848b8605Smrgstatic void 1997848b8605SmrgFake_glXDestroyWindow( Display *dpy, GLXWindow window ) 1998848b8605Smrg{ 1999848b8605Smrg XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window); 2000848b8605Smrg if (b) 2001848b8605Smrg XMesaDestroyBuffer(b); 2002848b8605Smrg /* don't destroy X window */ 2003848b8605Smrg} 2004848b8605Smrg 2005848b8605Smrg 2006848b8605Smrg/* XXX untested */ 2007848b8605Smrgstatic GLXPixmap 2008848b8605SmrgFake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, 2009848b8605Smrg const int *attribList ) 2010848b8605Smrg{ 2011848b8605Smrg XMesaVisual v = (XMesaVisual) config; 2012848b8605Smrg XMesaBuffer b; 2013848b8605Smrg const int *attr; 2014848b8605Smrg int target = 0, format = 0, mipmap = 0; 2015848b8605Smrg int value; 2016848b8605Smrg 2017848b8605Smrg if (!dpy || !config || !pixmap) 2018848b8605Smrg return 0; 2019848b8605Smrg 2020848b8605Smrg for (attr = attribList; attr && *attr; attr++) { 2021848b8605Smrg switch (*attr) { 2022848b8605Smrg case GLX_TEXTURE_FORMAT_EXT: 2023848b8605Smrg attr++; 2024848b8605Smrg switch (*attr) { 2025848b8605Smrg case GLX_TEXTURE_FORMAT_NONE_EXT: 2026848b8605Smrg case GLX_TEXTURE_FORMAT_RGB_EXT: 2027848b8605Smrg case GLX_TEXTURE_FORMAT_RGBA_EXT: 2028848b8605Smrg format = *attr; 2029848b8605Smrg break; 2030848b8605Smrg default: 2031848b8605Smrg /* error */ 2032848b8605Smrg return 0; 2033848b8605Smrg } 2034848b8605Smrg break; 2035848b8605Smrg case GLX_TEXTURE_TARGET_EXT: 2036848b8605Smrg attr++; 2037848b8605Smrg switch (*attr) { 2038848b8605Smrg case GLX_TEXTURE_1D_EXT: 2039848b8605Smrg case GLX_TEXTURE_2D_EXT: 2040848b8605Smrg case GLX_TEXTURE_RECTANGLE_EXT: 2041848b8605Smrg target = *attr; 2042848b8605Smrg break; 2043848b8605Smrg default: 2044848b8605Smrg /* error */ 2045848b8605Smrg return 0; 2046848b8605Smrg } 2047848b8605Smrg break; 2048848b8605Smrg case GLX_MIPMAP_TEXTURE_EXT: 2049848b8605Smrg attr++; 2050848b8605Smrg if (*attr) 2051848b8605Smrg mipmap = 1; 2052848b8605Smrg break; 2053848b8605Smrg default: 2054848b8605Smrg /* error */ 2055848b8605Smrg return 0; 2056848b8605Smrg } 2057848b8605Smrg } 2058848b8605Smrg 2059848b8605Smrg if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { 2060848b8605Smrg if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, 2061848b8605Smrg &value, GL_TRUE) != Success 2062848b8605Smrg || !value) { 2063848b8605Smrg return 0; /* error! */ 2064848b8605Smrg } 2065848b8605Smrg } 2066848b8605Smrg else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { 2067848b8605Smrg if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, 2068848b8605Smrg &value, GL_TRUE) != Success 2069848b8605Smrg || !value) { 2070848b8605Smrg return 0; /* error! */ 2071848b8605Smrg } 2072848b8605Smrg } 2073848b8605Smrg if (mipmap) { 2074848b8605Smrg if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, 2075848b8605Smrg &value, GL_TRUE) != Success 2076848b8605Smrg || !value) { 2077848b8605Smrg return 0; /* error! */ 2078848b8605Smrg } 2079848b8605Smrg } 2080848b8605Smrg if (target == GLX_TEXTURE_1D_EXT) { 2081848b8605Smrg if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2082848b8605Smrg &value, GL_TRUE) != Success 2083848b8605Smrg || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { 2084848b8605Smrg return 0; /* error! */ 2085848b8605Smrg } 2086848b8605Smrg } 2087848b8605Smrg else if (target == GLX_TEXTURE_2D_EXT) { 2088848b8605Smrg if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2089848b8605Smrg &value, GL_TRUE) != Success 2090848b8605Smrg || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { 2091848b8605Smrg return 0; /* error! */ 2092848b8605Smrg } 2093848b8605Smrg } 2094848b8605Smrg if (target == GLX_TEXTURE_RECTANGLE_EXT) { 2095848b8605Smrg if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2096848b8605Smrg &value, GL_TRUE) != Success 2097848b8605Smrg || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { 2098848b8605Smrg return 0; /* error! */ 2099848b8605Smrg } 2100848b8605Smrg } 2101848b8605Smrg 2102848b8605Smrg if (format || target || mipmap) { 2103848b8605Smrg /* texture from pixmap */ 2104848b8605Smrg b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); 2105848b8605Smrg } 2106848b8605Smrg else { 2107848b8605Smrg b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); 2108848b8605Smrg } 2109848b8605Smrg if (!b) { 2110848b8605Smrg return 0; 2111848b8605Smrg } 2112848b8605Smrg 2113848b8605Smrg return pixmap; 2114848b8605Smrg} 2115848b8605Smrg 2116848b8605Smrg 2117848b8605Smrgstatic void 2118848b8605SmrgFake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) 2119848b8605Smrg{ 2120848b8605Smrg XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap); 2121848b8605Smrg if (b) 2122848b8605Smrg XMesaDestroyBuffer(b); 2123848b8605Smrg /* don't destroy X pixmap */ 2124848b8605Smrg} 2125848b8605Smrg 2126848b8605Smrg 2127848b8605Smrgstatic GLXPbuffer 2128848b8605SmrgFake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, 2129848b8605Smrg const int *attribList ) 2130848b8605Smrg{ 2131848b8605Smrg XMesaVisual xmvis = (XMesaVisual) config; 2132848b8605Smrg XMesaBuffer xmbuf; 2133848b8605Smrg const int *attrib; 2134848b8605Smrg int width = 0, height = 0; 2135848b8605Smrg GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; 2136848b8605Smrg 2137848b8605Smrg (void) dpy; 2138848b8605Smrg 2139848b8605Smrg for (attrib = attribList; *attrib; attrib++) { 2140848b8605Smrg switch (*attrib) { 2141848b8605Smrg case GLX_PBUFFER_WIDTH: 2142848b8605Smrg attrib++; 2143848b8605Smrg width = *attrib; 2144848b8605Smrg break; 2145848b8605Smrg case GLX_PBUFFER_HEIGHT: 2146848b8605Smrg attrib++; 2147848b8605Smrg height = *attrib; 2148848b8605Smrg break; 2149848b8605Smrg case GLX_PRESERVED_CONTENTS: 2150848b8605Smrg attrib++; 2151848b8605Smrg preserveContents = *attrib; 2152848b8605Smrg break; 2153848b8605Smrg case GLX_LARGEST_PBUFFER: 2154848b8605Smrg attrib++; 2155848b8605Smrg useLargest = *attrib; 2156848b8605Smrg break; 2157848b8605Smrg default: 2158848b8605Smrg return 0; 2159848b8605Smrg } 2160848b8605Smrg } 2161848b8605Smrg 2162848b8605Smrg if (width == 0 || height == 0) 2163848b8605Smrg return 0; 2164848b8605Smrg 2165848b8605Smrg if (width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) { 2166848b8605Smrg /* If allocation would have failed and GLX_LARGEST_PBUFFER is set, 2167848b8605Smrg * allocate the largest possible buffer. 2168848b8605Smrg */ 2169848b8605Smrg if (useLargest) { 2170848b8605Smrg width = SWRAST_MAX_WIDTH; 2171848b8605Smrg height = SWRAST_MAX_HEIGHT; 2172848b8605Smrg } 2173848b8605Smrg } 2174848b8605Smrg 2175848b8605Smrg xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); 2176848b8605Smrg /* A GLXPbuffer handle must be an X Drawable because that's what 2177848b8605Smrg * glXMakeCurrent takes. 2178848b8605Smrg */ 2179848b8605Smrg if (xmbuf) { 2180848b8605Smrg xmbuf->largestPbuffer = useLargest; 2181848b8605Smrg xmbuf->preservedContents = preserveContents; 2182848b8605Smrg return (GLXPbuffer) xmbuf->frontxrb->pixmap; 2183848b8605Smrg } 2184848b8605Smrg else { 2185848b8605Smrg return 0; 2186848b8605Smrg } 2187848b8605Smrg} 2188848b8605Smrg 2189848b8605Smrg 2190848b8605Smrgstatic void 2191848b8605SmrgFake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) 2192848b8605Smrg{ 2193848b8605Smrg XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); 2194848b8605Smrg if (b) { 2195848b8605Smrg XMesaDestroyBuffer(b); 2196848b8605Smrg } 2197848b8605Smrg} 2198848b8605Smrg 2199848b8605Smrg 2200848b8605Smrgstatic void 2201848b8605SmrgFake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, 2202848b8605Smrg unsigned int *value ) 2203848b8605Smrg{ 2204848b8605Smrg XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); 2205848b8605Smrg if (!xmbuf) 2206848b8605Smrg return; 2207848b8605Smrg 2208848b8605Smrg /* make sure buffer's dimensions are up to date */ 2209848b8605Smrg xmesa_check_and_update_buffer_size(NULL, xmbuf); 2210848b8605Smrg 2211848b8605Smrg switch (attribute) { 2212848b8605Smrg case GLX_WIDTH: 2213848b8605Smrg *value = xmbuf->mesa_buffer.Width; 2214848b8605Smrg break; 2215848b8605Smrg case GLX_HEIGHT: 2216848b8605Smrg *value = xmbuf->mesa_buffer.Height; 2217848b8605Smrg break; 2218848b8605Smrg case GLX_PRESERVED_CONTENTS: 2219848b8605Smrg *value = xmbuf->preservedContents; 2220848b8605Smrg break; 2221848b8605Smrg case GLX_LARGEST_PBUFFER: 2222848b8605Smrg *value = xmbuf->largestPbuffer; 2223848b8605Smrg break; 2224848b8605Smrg case GLX_FBCONFIG_ID: 2225848b8605Smrg *value = xmbuf->xm_visual->visinfo->visualid; 2226848b8605Smrg return; 2227848b8605Smrg case GLX_TEXTURE_FORMAT_EXT: 2228848b8605Smrg *value = xmbuf->TextureFormat; 2229848b8605Smrg break; 2230848b8605Smrg case GLX_TEXTURE_TARGET_EXT: 2231848b8605Smrg *value = xmbuf->TextureTarget; 2232848b8605Smrg break; 2233848b8605Smrg case GLX_MIPMAP_TEXTURE_EXT: 2234848b8605Smrg *value = xmbuf->TextureMipmap; 2235848b8605Smrg break; 2236848b8605Smrg 2237848b8605Smrg default: 2238848b8605Smrg return; /* raise BadValue error */ 2239848b8605Smrg } 2240848b8605Smrg} 2241848b8605Smrg 2242848b8605Smrg 2243848b8605Smrgstatic GLXContext 2244848b8605SmrgFake_glXCreateNewContext( Display *dpy, GLXFBConfig config, 2245848b8605Smrg int renderType, GLXContext shareList, Bool direct ) 2246848b8605Smrg{ 2247848b8605Smrg XMesaContext xmCtx; 2248848b8605Smrg XMesaVisual xmvis = (XMesaVisual) config; 2249848b8605Smrg 2250848b8605Smrg if (!dpy || !config || 2251848b8605Smrg (renderType != GLX_RGBA_TYPE && 2252848b8605Smrg renderType != GLX_COLOR_INDEX_TYPE && 2253848b8605Smrg renderType != GLX_RGBA_FLOAT_TYPE_ARB && 2254848b8605Smrg renderType != GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT)) 2255848b8605Smrg return 0; 2256848b8605Smrg 2257848b8605Smrg /* deallocate unused windows/buffers */ 2258848b8605Smrg XMesaGarbageCollect(dpy); 2259848b8605Smrg 2260848b8605Smrg xmCtx = XMesaCreateContext(xmvis, (XMesaContext) shareList); 2261848b8605Smrg 2262848b8605Smrg return (GLXContext) xmCtx; 2263848b8605Smrg} 2264848b8605Smrg 2265848b8605Smrg 2266848b8605Smrgstatic int 2267848b8605SmrgFake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) 2268848b8605Smrg{ 2269848b8605Smrg XMesaContext xmctx = (XMesaContext) ctx; 2270848b8605Smrg (void) dpy; 2271848b8605Smrg (void) ctx; 2272848b8605Smrg 2273848b8605Smrg switch (attribute) { 2274848b8605Smrg case GLX_FBCONFIG_ID: 2275848b8605Smrg *value = xmctx->xm_visual->visinfo->visualid; 2276848b8605Smrg break; 2277848b8605Smrg case GLX_RENDER_TYPE: 2278848b8605Smrg *value = GLX_RGBA_TYPE; 2279848b8605Smrg break; 2280848b8605Smrg case GLX_SCREEN: 2281848b8605Smrg *value = 0; 2282848b8605Smrg return Success; 2283848b8605Smrg default: 2284848b8605Smrg return GLX_BAD_ATTRIBUTE; 2285848b8605Smrg } 2286848b8605Smrg return 0; 2287848b8605Smrg} 2288848b8605Smrg 2289848b8605Smrg 2290848b8605Smrgstatic void 2291848b8605SmrgFake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) 2292848b8605Smrg{ 2293848b8605Smrg XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2294848b8605Smrg if (xmbuf) 2295848b8605Smrg xmbuf->selectedEvents = mask; 2296848b8605Smrg} 2297848b8605Smrg 2298848b8605Smrg 2299848b8605Smrgstatic void 2300848b8605SmrgFake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, 2301848b8605Smrg unsigned long *mask ) 2302848b8605Smrg{ 2303848b8605Smrg XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2304848b8605Smrg if (xmbuf) 2305848b8605Smrg *mask = xmbuf->selectedEvents; 2306848b8605Smrg else 2307848b8605Smrg *mask = 0; 2308848b8605Smrg} 2309848b8605Smrg 2310848b8605Smrg 2311848b8605Smrg 2312848b8605Smrg/*** GLX_SGI_swap_control ***/ 2313848b8605Smrg 2314848b8605Smrgstatic int 2315848b8605SmrgFake_glXSwapIntervalSGI(int interval) 2316848b8605Smrg{ 2317848b8605Smrg (void) interval; 2318848b8605Smrg return 0; 2319848b8605Smrg} 2320848b8605Smrg 2321848b8605Smrg 2322848b8605Smrg 2323848b8605Smrg/*** GLX_SGI_video_sync ***/ 2324848b8605Smrg 2325848b8605Smrgstatic unsigned int FrameCounter = 0; 2326848b8605Smrg 2327848b8605Smrgstatic int 2328848b8605SmrgFake_glXGetVideoSyncSGI(unsigned int *count) 2329848b8605Smrg{ 2330848b8605Smrg /* this is a bogus implementation */ 2331848b8605Smrg *count = FrameCounter++; 2332848b8605Smrg return 0; 2333848b8605Smrg} 2334848b8605Smrg 2335848b8605Smrgstatic int 2336848b8605SmrgFake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) 2337848b8605Smrg{ 2338848b8605Smrg if (divisor <= 0 || remainder < 0) 2339848b8605Smrg return GLX_BAD_VALUE; 2340848b8605Smrg /* this is a bogus implementation */ 2341848b8605Smrg FrameCounter++; 2342848b8605Smrg while (FrameCounter % divisor != remainder) 2343848b8605Smrg FrameCounter++; 2344848b8605Smrg *count = FrameCounter; 2345848b8605Smrg return 0; 2346848b8605Smrg} 2347848b8605Smrg 2348848b8605Smrg 2349848b8605Smrg 2350848b8605Smrg/*** GLX_SGI_make_current_read ***/ 2351848b8605Smrg 2352848b8605Smrgstatic Bool 2353848b8605SmrgFake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) 2354848b8605Smrg{ 2355848b8605Smrg return Fake_glXMakeContextCurrent( dpy, draw, read, ctx ); 2356848b8605Smrg} 2357848b8605Smrg 2358848b8605Smrg/* not used 2359848b8605Smrgstatic GLXDrawable 2360848b8605SmrgFake_glXGetCurrentReadDrawableSGI(void) 2361848b8605Smrg{ 2362848b8605Smrg return 0; 2363848b8605Smrg} 2364848b8605Smrg*/ 2365848b8605Smrg 2366848b8605Smrg 2367848b8605Smrg/*** GLX_SGIX_video_source ***/ 2368848b8605Smrg#if defined(_VL_H) 2369848b8605Smrg 2370848b8605Smrgstatic GLXVideoSourceSGIX 2371848b8605SmrgFake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) 2372848b8605Smrg{ 2373848b8605Smrg (void) dpy; 2374848b8605Smrg (void) screen; 2375848b8605Smrg (void) server; 2376848b8605Smrg (void) path; 2377848b8605Smrg (void) nodeClass; 2378848b8605Smrg (void) drainNode; 2379848b8605Smrg return 0; 2380848b8605Smrg} 2381848b8605Smrg 2382848b8605Smrgstatic void 2383848b8605SmrgFake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) 2384848b8605Smrg{ 2385848b8605Smrg (void) dpy; 2386848b8605Smrg (void) src; 2387848b8605Smrg} 2388848b8605Smrg 2389848b8605Smrg#endif 2390848b8605Smrg 2391848b8605Smrg 2392848b8605Smrg/*** GLX_EXT_import_context ***/ 2393848b8605Smrg 2394848b8605Smrgstatic void 2395848b8605SmrgFake_glXFreeContextEXT(Display *dpy, GLXContext context) 2396848b8605Smrg{ 2397848b8605Smrg (void) dpy; 2398848b8605Smrg (void) context; 2399848b8605Smrg} 2400848b8605Smrg 2401848b8605Smrgstatic GLXContextID 2402848b8605SmrgFake_glXGetContextIDEXT(const GLXContext context) 2403848b8605Smrg{ 2404848b8605Smrg (void) context; 2405848b8605Smrg return 0; 2406848b8605Smrg} 2407848b8605Smrg 2408848b8605Smrgstatic GLXContext 2409848b8605SmrgFake_glXImportContextEXT(Display *dpy, GLXContextID contextID) 2410848b8605Smrg{ 2411848b8605Smrg (void) dpy; 2412848b8605Smrg (void) contextID; 2413848b8605Smrg return 0; 2414848b8605Smrg} 2415848b8605Smrg 2416848b8605Smrgstatic int 2417848b8605SmrgFake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) 2418848b8605Smrg{ 2419848b8605Smrg (void) dpy; 2420848b8605Smrg (void) context; 2421848b8605Smrg (void) attribute; 2422848b8605Smrg (void) value; 2423848b8605Smrg return 0; 2424848b8605Smrg} 2425848b8605Smrg 2426848b8605Smrg 2427848b8605Smrg 2428848b8605Smrg/*** GLX_SGIX_fbconfig ***/ 2429848b8605Smrg 2430848b8605Smrgstatic int 2431848b8605SmrgFake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) 2432848b8605Smrg{ 2433848b8605Smrg return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value); 2434848b8605Smrg} 2435848b8605Smrg 2436848b8605Smrgstatic GLXFBConfigSGIX * 2437848b8605SmrgFake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) 2438848b8605Smrg{ 2439848b8605Smrg return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements); 2440848b8605Smrg} 2441848b8605Smrg 2442848b8605Smrg 2443848b8605Smrgstatic GLXPixmap 2444848b8605SmrgFake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) 2445848b8605Smrg{ 2446848b8605Smrg XMesaVisual xmvis = (XMesaVisual) config; 2447848b8605Smrg XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); 2448848b8605Smrg return xmbuf->frontxrb->pixmap; /* need to return an X ID */ 2449848b8605Smrg} 2450848b8605Smrg 2451848b8605Smrg 2452848b8605Smrgstatic GLXContext 2453848b8605SmrgFake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) 2454848b8605Smrg{ 2455848b8605Smrg XMesaContext xmCtx; 2456848b8605Smrg XMesaVisual xmvis = (XMesaVisual) config; 2457848b8605Smrg 2458848b8605Smrg /* deallocate unused windows/buffers */ 2459848b8605Smrg XMesaGarbageCollect(dpy); 2460848b8605Smrg 2461848b8605Smrg xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list); 2462848b8605Smrg 2463848b8605Smrg return (GLXContext) xmCtx; 2464848b8605Smrg} 2465848b8605Smrg 2466848b8605Smrg 2467848b8605Smrgstatic XVisualInfo * 2468848b8605SmrgFake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) 2469848b8605Smrg{ 2470848b8605Smrg return Fake_glXGetVisualFromFBConfig(dpy, config); 2471848b8605Smrg} 2472848b8605Smrg 2473848b8605Smrg 2474848b8605Smrgstatic GLXFBConfigSGIX 2475848b8605SmrgFake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) 2476848b8605Smrg{ 2477848b8605Smrg XMesaVisual xmvis = find_glx_visual(dpy, vis); 2478848b8605Smrg if (!xmvis) { 2479848b8605Smrg /* This visual wasn't found with glXChooseVisual() */ 2480848b8605Smrg xmvis = create_glx_visual(dpy, vis); 2481848b8605Smrg } 2482848b8605Smrg 2483848b8605Smrg return (GLXFBConfigSGIX) xmvis; 2484848b8605Smrg} 2485848b8605Smrg 2486848b8605Smrg 2487848b8605Smrg 2488848b8605Smrg/*** GLX_SGIX_pbuffer ***/ 2489848b8605Smrg 2490848b8605Smrgstatic GLXPbufferSGIX 2491848b8605SmrgFake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, 2492848b8605Smrg unsigned int width, unsigned int height, 2493848b8605Smrg int *attribList) 2494848b8605Smrg{ 2495848b8605Smrg XMesaVisual xmvis = (XMesaVisual) config; 2496848b8605Smrg XMesaBuffer xmbuf; 2497848b8605Smrg const int *attrib; 2498848b8605Smrg GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; 2499848b8605Smrg 2500848b8605Smrg (void) dpy; 2501848b8605Smrg 2502848b8605Smrg for (attrib = attribList; attrib && *attrib; attrib++) { 2503848b8605Smrg switch (*attrib) { 2504848b8605Smrg case GLX_PRESERVED_CONTENTS_SGIX: 2505848b8605Smrg attrib++; 2506848b8605Smrg preserveContents = *attrib; /* ignored */ 2507848b8605Smrg break; 2508848b8605Smrg case GLX_LARGEST_PBUFFER_SGIX: 2509848b8605Smrg attrib++; 2510848b8605Smrg useLargest = *attrib; /* ignored */ 2511848b8605Smrg break; 2512848b8605Smrg default: 2513848b8605Smrg return 0; 2514848b8605Smrg } 2515848b8605Smrg } 2516848b8605Smrg 2517848b8605Smrg /* not used at this time */ 2518848b8605Smrg (void) useLargest; 2519848b8605Smrg (void) preserveContents; 2520848b8605Smrg 2521848b8605Smrg xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); 2522848b8605Smrg /* A GLXPbuffer handle must be an X Drawable because that's what 2523848b8605Smrg * glXMakeCurrent takes. 2524848b8605Smrg */ 2525848b8605Smrg return (GLXPbuffer) xmbuf->frontxrb->pixmap; 2526848b8605Smrg} 2527848b8605Smrg 2528848b8605Smrg 2529848b8605Smrgstatic void 2530848b8605SmrgFake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) 2531848b8605Smrg{ 2532848b8605Smrg XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); 2533848b8605Smrg if (xmbuf) { 2534848b8605Smrg XMesaDestroyBuffer(xmbuf); 2535848b8605Smrg } 2536848b8605Smrg} 2537848b8605Smrg 2538848b8605Smrg 2539848b8605Smrgstatic int 2540848b8605SmrgFake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) 2541848b8605Smrg{ 2542848b8605Smrg const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); 2543848b8605Smrg 2544848b8605Smrg if (!xmbuf) { 2545848b8605Smrg /* Generate GLXBadPbufferSGIX for bad pbuffer */ 2546848b8605Smrg return 0; 2547848b8605Smrg } 2548848b8605Smrg 2549848b8605Smrg switch (attribute) { 2550848b8605Smrg case GLX_PRESERVED_CONTENTS_SGIX: 2551848b8605Smrg *value = xmbuf->preservedContents; 2552848b8605Smrg break; 2553848b8605Smrg case GLX_LARGEST_PBUFFER_SGIX: 2554848b8605Smrg *value = xmbuf->largestPbuffer; 2555848b8605Smrg break; 2556848b8605Smrg case GLX_WIDTH_SGIX: 2557848b8605Smrg *value = xmbuf->mesa_buffer.Width; 2558848b8605Smrg break; 2559848b8605Smrg case GLX_HEIGHT_SGIX: 2560848b8605Smrg *value = xmbuf->mesa_buffer.Height; 2561848b8605Smrg break; 2562848b8605Smrg case GLX_EVENT_MASK_SGIX: 2563848b8605Smrg *value = 0; /* XXX might be wrong */ 2564848b8605Smrg break; 2565848b8605Smrg default: 2566848b8605Smrg *value = 0; 2567848b8605Smrg } 2568848b8605Smrg return 0; 2569848b8605Smrg} 2570848b8605Smrg 2571848b8605Smrg 2572848b8605Smrgstatic void 2573848b8605SmrgFake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) 2574848b8605Smrg{ 2575848b8605Smrg XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2576848b8605Smrg if (xmbuf) { 2577848b8605Smrg /* Note: we'll never generate clobber events */ 2578848b8605Smrg xmbuf->selectedEvents = mask; 2579848b8605Smrg } 2580848b8605Smrg} 2581848b8605Smrg 2582848b8605Smrg 2583848b8605Smrgstatic void 2584848b8605SmrgFake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) 2585848b8605Smrg{ 2586848b8605Smrg XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2587848b8605Smrg if (xmbuf) { 2588848b8605Smrg *mask = xmbuf->selectedEvents; 2589848b8605Smrg } 2590848b8605Smrg else { 2591848b8605Smrg *mask = 0; 2592848b8605Smrg } 2593848b8605Smrg} 2594848b8605Smrg 2595848b8605Smrg 2596848b8605Smrg 2597848b8605Smrg/*** GLX_SGI_cushion ***/ 2598848b8605Smrg 2599848b8605Smrgstatic void 2600848b8605SmrgFake_glXCushionSGI(Display *dpy, Window win, float cushion) 2601848b8605Smrg{ 2602848b8605Smrg (void) dpy; 2603848b8605Smrg (void) win; 2604848b8605Smrg (void) cushion; 2605848b8605Smrg} 2606848b8605Smrg 2607848b8605Smrg 2608848b8605Smrg 2609848b8605Smrg/*** GLX_SGIX_video_resize ***/ 2610848b8605Smrg 2611848b8605Smrgstatic int 2612848b8605SmrgFake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) 2613848b8605Smrg{ 2614848b8605Smrg (void) dpy; 2615848b8605Smrg (void) screen; 2616848b8605Smrg (void) channel; 2617848b8605Smrg (void) window; 2618848b8605Smrg return 0; 2619848b8605Smrg} 2620848b8605Smrg 2621848b8605Smrgstatic int 2622848b8605SmrgFake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) 2623848b8605Smrg{ 2624848b8605Smrg (void) dpy; 2625848b8605Smrg (void) screen; 2626848b8605Smrg (void) channel; 2627848b8605Smrg (void) x; 2628848b8605Smrg (void) y; 2629848b8605Smrg (void) w; 2630848b8605Smrg (void) h; 2631848b8605Smrg return 0; 2632848b8605Smrg} 2633848b8605Smrg 2634848b8605Smrgstatic int 2635848b8605SmrgFake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) 2636848b8605Smrg{ 2637848b8605Smrg (void) dpy; 2638848b8605Smrg (void) screen; 2639848b8605Smrg (void) channel; 2640848b8605Smrg (void) x; 2641848b8605Smrg (void) y; 2642848b8605Smrg (void) w; 2643848b8605Smrg (void) h; 2644848b8605Smrg return 0; 2645848b8605Smrg} 2646848b8605Smrg 2647848b8605Smrgstatic int 2648848b8605SmrgFake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) 2649848b8605Smrg{ 2650848b8605Smrg (void) dpy; 2651848b8605Smrg (void) screen; 2652848b8605Smrg (void) channel; 2653848b8605Smrg (void) dx; 2654848b8605Smrg (void) dy; 2655848b8605Smrg (void) dw; 2656848b8605Smrg (void) dh; 2657848b8605Smrg return 0; 2658848b8605Smrg} 2659848b8605Smrg 2660848b8605Smrgstatic int 2661848b8605SmrgFake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) 2662848b8605Smrg{ 2663848b8605Smrg (void) dpy; 2664848b8605Smrg (void) screen; 2665848b8605Smrg (void) channel; 2666848b8605Smrg (void) synctype; 2667848b8605Smrg return 0; 2668848b8605Smrg} 2669848b8605Smrg 2670848b8605Smrg 2671848b8605Smrg 2672848b8605Smrg/*** GLX_SGIX_dmbuffer **/ 2673848b8605Smrg 2674848b8605Smrg#if defined(_DM_BUFFER_H_) 2675848b8605Smrgstatic Bool 2676848b8605SmrgFake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) 2677848b8605Smrg{ 2678848b8605Smrg (void) dpy; 2679848b8605Smrg (void) pbuffer; 2680848b8605Smrg (void) params; 2681848b8605Smrg (void) dmbuffer; 2682848b8605Smrg return False; 2683848b8605Smrg} 2684848b8605Smrg#endif 2685848b8605Smrg 2686848b8605Smrg 2687848b8605Smrg/*** GLX_SUN_get_transparent_index ***/ 2688848b8605Smrg 2689848b8605Smrgstatic Status 2690848b8605SmrgFake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) 2691848b8605Smrg{ 2692848b8605Smrg (void) dpy; 2693848b8605Smrg (void) overlay; 2694848b8605Smrg (void) underlay; 2695848b8605Smrg (void) pTransparent; 2696848b8605Smrg return 0; 2697848b8605Smrg} 2698848b8605Smrg 2699848b8605Smrg 2700848b8605Smrg 2701848b8605Smrg/*** GLX_MESA_release_buffers ***/ 2702848b8605Smrg 2703848b8605Smrg/* 2704848b8605Smrg * Release the depth, stencil, accum buffers attached to a GLXDrawable 2705848b8605Smrg * (a window or pixmap) prior to destroying the GLXDrawable. 2706848b8605Smrg */ 2707848b8605Smrgstatic Bool 2708848b8605SmrgFake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) 2709848b8605Smrg{ 2710848b8605Smrg XMesaBuffer b = XMesaFindBuffer(dpy, d); 2711848b8605Smrg if (b) { 2712848b8605Smrg XMesaDestroyBuffer(b); 2713848b8605Smrg return True; 2714848b8605Smrg } 2715848b8605Smrg return False; 2716848b8605Smrg} 2717848b8605Smrg 2718848b8605Smrg 2719848b8605Smrg 2720848b8605Smrg/*** GLX_EXT_texture_from_pixmap ***/ 2721848b8605Smrg 2722848b8605Smrgstatic void 2723848b8605SmrgFake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, 2724848b8605Smrg const int *attrib_list) 2725848b8605Smrg{ 2726848b8605Smrg XMesaBuffer b = XMesaFindBuffer(dpy, drawable); 2727848b8605Smrg if (b) 2728848b8605Smrg XMesaBindTexImage(dpy, b, buffer, attrib_list); 2729848b8605Smrg} 2730848b8605Smrg 2731848b8605Smrgstatic void 2732848b8605SmrgFake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) 2733848b8605Smrg{ 2734848b8605Smrg XMesaBuffer b = XMesaFindBuffer(dpy, drawable); 2735848b8605Smrg if (b) 2736848b8605Smrg XMesaReleaseTexImage(dpy, b, buffer); 2737848b8605Smrg} 2738848b8605Smrg 2739848b8605Smrg 2740b8e80941Smrgstatic GLXContext 2741b8e80941SmrgFake_glXCreateContextAttribs(Display *dpy, GLXFBConfig config, 2742b8e80941Smrg GLXContext share_context, Bool direct, 2743b8e80941Smrg const int *attrib_list) 2744b8e80941Smrg{ 2745b8e80941Smrg XMesaContext xmCtx; 2746b8e80941Smrg XMesaVisual xmvis = (XMesaVisual) config; 2747b8e80941Smrg int i; 2748b8e80941Smrg int major = 0, minor = 0, ctxFlags = 0, profileFlags = 0; 2749b8e80941Smrg 2750b8e80941Smrg for (i = 0; attrib_list[i]; i += 2) { 2751b8e80941Smrg switch (attrib_list[i]) { 2752b8e80941Smrg case GLX_CONTEXT_MAJOR_VERSION_ARB: 2753b8e80941Smrg major = attrib_list[i + 1]; 2754b8e80941Smrg break; 2755b8e80941Smrg case GLX_CONTEXT_MINOR_VERSION_ARB: 2756b8e80941Smrg minor = attrib_list[i + 1]; 2757b8e80941Smrg break; 2758b8e80941Smrg case GLX_CONTEXT_FLAGS_ARB: 2759b8e80941Smrg ctxFlags = attrib_list[i + 1]; 2760b8e80941Smrg break; 2761b8e80941Smrg case GLX_CONTEXT_PROFILE_MASK_ARB: 2762b8e80941Smrg profileFlags = attrib_list[i + 1]; 2763b8e80941Smrg break; 2764b8e80941Smrg default: 2765b8e80941Smrg _mesa_warning(NULL, "Unexpected attribute 0x%x in " 2766b8e80941Smrg "glXCreateContextAttribs()\n", attrib_list[i]); 2767b8e80941Smrg return 0; 2768b8e80941Smrg } 2769b8e80941Smrg } 2770b8e80941Smrg 2771b8e80941Smrg if (major * 10 + minor > 21) { 2772b8e80941Smrg /* swrast only supports GL 2.1 and earlier */ 2773b8e80941Smrg return 0; 2774b8e80941Smrg } 2775b8e80941Smrg 2776b8e80941Smrg /* These are ignored for now. We'd have to enhance XMesaCreateContext 2777b8e80941Smrg * to take these flags and the version, at least. 2778b8e80941Smrg */ 2779b8e80941Smrg (void) ctxFlags; 2780b8e80941Smrg (void) profileFlags; 2781b8e80941Smrg 2782b8e80941Smrg /* deallocate unused windows/buffers */ 2783b8e80941Smrg XMesaGarbageCollect(dpy); 2784b8e80941Smrg 2785b8e80941Smrg xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_context); 2786b8e80941Smrg 2787b8e80941Smrg return (GLXContext) xmCtx; 2788b8e80941Smrg} 2789b8e80941Smrg 2790b8e80941Smrg 2791848b8605Smrg/* silence warning */ 2792848b8605Smrgextern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); 2793848b8605Smrg 2794848b8605Smrg 2795848b8605Smrg/** 2796848b8605Smrg * Create a new GLX API dispatch table with its function pointers 2797848b8605Smrg * initialized to point to Mesa's "fake" GLX API functions. 2798848b8605Smrg * Note: there's a similar function (_real_GetGLXDispatchTable) that 2799848b8605Smrg * returns a new dispatch table with all pointers initalized to point 2800848b8605Smrg * to "real" GLX functions (which understand GLX wire protocol, etc). 2801848b8605Smrg */ 2802848b8605Smrgstruct _glxapi_table * 2803848b8605Smrg_mesa_GetGLXDispatchTable(void) 2804848b8605Smrg{ 2805848b8605Smrg static struct _glxapi_table glx; 2806848b8605Smrg 2807848b8605Smrg /* be sure our dispatch table size <= libGL's table */ 2808848b8605Smrg { 2809848b8605Smrg GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); 2810848b8605Smrg (void) size; 2811848b8605Smrg assert(_glxapi_get_dispatch_table_size() >= size); 2812848b8605Smrg } 2813848b8605Smrg 2814848b8605Smrg /* initialize the whole table to no-ops */ 2815848b8605Smrg _glxapi_set_no_op_table(&glx); 2816848b8605Smrg 2817848b8605Smrg /* now initialize the table with the functions I implement */ 2818848b8605Smrg glx.ChooseVisual = Fake_glXChooseVisual; 2819848b8605Smrg glx.CopyContext = Fake_glXCopyContext; 2820848b8605Smrg glx.CreateContext = Fake_glXCreateContext; 2821848b8605Smrg glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap; 2822848b8605Smrg glx.DestroyContext = Fake_glXDestroyContext; 2823848b8605Smrg glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; 2824848b8605Smrg glx.GetConfig = Fake_glXGetConfig; 2825848b8605Smrg glx.GetCurrentContext = Fake_glXGetCurrentContext; 2826848b8605Smrg /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ 2827848b8605Smrg glx.IsDirect = Fake_glXIsDirect; 2828848b8605Smrg glx.MakeCurrent = Fake_glXMakeCurrent; 2829848b8605Smrg glx.QueryExtension = Fake_glXQueryExtension; 2830848b8605Smrg glx.QueryVersion = Fake_glXQueryVersion; 2831848b8605Smrg glx.SwapBuffers = Fake_glXSwapBuffers; 2832848b8605Smrg glx.UseXFont = Fake_glXUseXFont; 2833848b8605Smrg glx.WaitGL = Fake_glXWaitGL; 2834848b8605Smrg glx.WaitX = Fake_glXWaitX; 2835848b8605Smrg 2836848b8605Smrg /*** GLX_VERSION_1_1 ***/ 2837848b8605Smrg glx.GetClientString = Fake_glXGetClientString; 2838848b8605Smrg glx.QueryExtensionsString = Fake_glXQueryExtensionsString; 2839848b8605Smrg glx.QueryServerString = Fake_glXQueryServerString; 2840848b8605Smrg 2841848b8605Smrg /*** GLX_VERSION_1_2 ***/ 2842848b8605Smrg /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/ 2843848b8605Smrg 2844848b8605Smrg /*** GLX_VERSION_1_3 ***/ 2845848b8605Smrg glx.ChooseFBConfig = Fake_glXChooseFBConfig; 2846848b8605Smrg glx.CreateNewContext = Fake_glXCreateNewContext; 2847848b8605Smrg glx.CreatePbuffer = Fake_glXCreatePbuffer; 2848848b8605Smrg glx.CreatePixmap = Fake_glXCreatePixmap; 2849848b8605Smrg glx.CreateWindow = Fake_glXCreateWindow; 2850848b8605Smrg glx.DestroyPbuffer = Fake_glXDestroyPbuffer; 2851848b8605Smrg glx.DestroyPixmap = Fake_glXDestroyPixmap; 2852848b8605Smrg glx.DestroyWindow = Fake_glXDestroyWindow; 2853848b8605Smrg /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/ 2854848b8605Smrg glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib; 2855848b8605Smrg glx.GetFBConfigs = Fake_glXGetFBConfigs; 2856848b8605Smrg glx.GetSelectedEvent = Fake_glXGetSelectedEvent; 2857848b8605Smrg glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig; 2858848b8605Smrg glx.MakeContextCurrent = Fake_glXMakeContextCurrent; 2859848b8605Smrg glx.QueryContext = Fake_glXQueryContext; 2860848b8605Smrg glx.QueryDrawable = Fake_glXQueryDrawable; 2861848b8605Smrg glx.SelectEvent = Fake_glXSelectEvent; 2862848b8605Smrg 2863848b8605Smrg /*** GLX_SGI_swap_control ***/ 2864848b8605Smrg glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI; 2865848b8605Smrg 2866848b8605Smrg /*** GLX_SGI_video_sync ***/ 2867848b8605Smrg glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI; 2868848b8605Smrg glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI; 2869848b8605Smrg 2870848b8605Smrg /*** GLX_SGI_make_current_read ***/ 2871848b8605Smrg glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI; 2872848b8605Smrg /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/ 2873848b8605Smrg 2874848b8605Smrg/*** GLX_SGIX_video_source ***/ 2875848b8605Smrg#if defined(_VL_H) 2876848b8605Smrg glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX; 2877848b8605Smrg glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX; 2878848b8605Smrg#endif 2879848b8605Smrg 2880848b8605Smrg /*** GLX_EXT_import_context ***/ 2881848b8605Smrg glx.FreeContextEXT = Fake_glXFreeContextEXT; 2882848b8605Smrg glx.GetContextIDEXT = Fake_glXGetContextIDEXT; 2883848b8605Smrg /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/ 2884848b8605Smrg glx.ImportContextEXT = Fake_glXImportContextEXT; 2885848b8605Smrg glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT; 2886848b8605Smrg 2887848b8605Smrg /*** GLX_SGIX_fbconfig ***/ 2888848b8605Smrg glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX; 2889848b8605Smrg glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX; 2890848b8605Smrg glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX; 2891848b8605Smrg glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX; 2892848b8605Smrg glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX; 2893848b8605Smrg glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX; 2894848b8605Smrg 2895848b8605Smrg /*** GLX_SGIX_pbuffer ***/ 2896848b8605Smrg glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX; 2897848b8605Smrg glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX; 2898848b8605Smrg glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX; 2899848b8605Smrg glx.SelectEventSGIX = Fake_glXSelectEventSGIX; 2900848b8605Smrg glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX; 2901848b8605Smrg 2902848b8605Smrg /*** GLX_SGI_cushion ***/ 2903848b8605Smrg glx.CushionSGI = Fake_glXCushionSGI; 2904848b8605Smrg 2905848b8605Smrg /*** GLX_SGIX_video_resize ***/ 2906848b8605Smrg glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX; 2907848b8605Smrg glx.ChannelRectSGIX = Fake_glXChannelRectSGIX; 2908848b8605Smrg glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX; 2909848b8605Smrg glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX; 2910848b8605Smrg glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX; 2911848b8605Smrg 2912848b8605Smrg /*** GLX_SGIX_dmbuffer **/ 2913848b8605Smrg#if defined(_DM_BUFFER_H_) 2914848b8605Smrg glx.AssociateDMPbufferSGIX = NULL; 2915848b8605Smrg#endif 2916848b8605Smrg 2917848b8605Smrg /*** GLX_SUN_get_transparent_index ***/ 2918848b8605Smrg glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; 2919848b8605Smrg 2920848b8605Smrg /*** GLX_MESA_copy_sub_buffer ***/ 2921848b8605Smrg glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA; 2922848b8605Smrg 2923848b8605Smrg /*** GLX_MESA_release_buffers ***/ 2924848b8605Smrg glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA; 2925848b8605Smrg 2926848b8605Smrg /*** GLX_MESA_pixmap_colormap ***/ 2927848b8605Smrg glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; 2928848b8605Smrg 2929848b8605Smrg /*** GLX_EXT_texture_from_pixmap ***/ 2930848b8605Smrg glx.BindTexImageEXT = Fake_glXBindTexImageEXT; 2931848b8605Smrg glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; 2932848b8605Smrg 2933b8e80941Smrg glx.CreateContextAttribs = Fake_glXCreateContextAttribs; 2934848b8605Smrg return &glx; 2935848b8605Smrg} 2936