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