1 /* $Id: fakeglx.c,v 1.26 2000/03/17 15:33:09 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 * This is an emulation of the GLX API which allows Mesa/GLX-based programs
30 * to run on X servers which do not have the real GLX extension.
32 * Thanks to the contributors:
34 * Initial version: Philip Brown (philb@CSUA.Berkeley.EDU)
35 * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
36 * Further visual-handling refinements: Wolfram Gloger
37 * (wmglo@Dent.MED.Uni-Muenchen.DE).
40 * Don't be fooled, stereo isn't supported yet.
45 #include "glxheader.h"
55 /* This indicates the client-side GLX API and GLX encoder version. */
56 #define CLIENT_MAJOR_VERSION 1
57 #define CLIENT_MINOR_VERSION 2
59 /* This indicates the server-side GLX decoder version.
60 * GLX 1.3 indicates OpenGL 1.2 support
62 #define SERVER_MAJOR_VERSION 1
63 #define SERVER_MINOR_VERSION 3
65 /* This is appended onto the glXGetClient/ServerString version strings. */
66 #define MESA_GLX_VERSION "Mesa 3.3"
68 /* Who implemented this GLX? */
69 #define VENDOR "Brian Paul"
73 /* Silence compiler warnings */
74 extern void Fake_glXDummyFunc( void );
75 void Fake_glXDummyFunc( void )
89 #define MAX_VISUALS 100
90 static XMesaVisual VisualTable
[MAX_VISUALS
];
91 static int NumVisuals
= 0;
96 * This struct and some code fragments borrowed
97 * from Mark Kilgard's GLUT library.
99 typedef struct _OverlayInfo
{
100 /* Avoid 64-bit portability problems by being careful to use
101 longs due to the way XGetWindowProperty is specified. Note
102 that these parameters are passed as CARD32s over X
104 unsigned long overlay_visual
;
105 long transparent_type
;
112 /* Macro to handle c_class vs class field name in XVisualInfo struct */
113 #if defined(__cplusplus) || defined(c_plusplus)
114 #define CLASS c_class
123 * Test if the given XVisualInfo is usable for Mesa rendering.
125 static GLboolean
is_usable_visual( XVisualInfo
*vinfo
)
127 switch (vinfo
->CLASS
) {
130 /* Any StaticGray/GrayScale visual works in RGB or CI mode */
134 /* Any StaticColor/PseudoColor visual of at least 4 bits */
135 if (vinfo
->depth
>=4) {
143 /* Any depth of TrueColor or DirectColor works in RGB mode */
146 /* This should never happen */
154 * Return the level (overlay, normal, underlay) of a given XVisualInfo.
155 * Input: dpy - the X display
156 * vinfo - the XVisualInfo to test
157 * Return: level of the visual:
159 * >0 = overlay planes
160 * <0 = underlay planes
162 static int level_of_visual( Display
*dpy
, XVisualInfo
*vinfo
)
164 Atom overlayVisualsAtom
;
165 OverlayInfo
*overlay_info
= NULL
;
166 int numOverlaysPerScreen
;
170 unsigned long sizeData
, bytesLeft
;
174 * The SERVER_OVERLAY_VISUALS property on the root window contains
175 * a list of overlay visuals. Get that list now.
177 overlayVisualsAtom
= XInternAtom(dpy
,"SERVER_OVERLAY_VISUALS", True
);
178 if (overlayVisualsAtom
== None
) {
182 status
= XGetWindowProperty(dpy
, RootWindow( dpy
, vinfo
->screen
),
183 overlayVisualsAtom
, 0L, (long) 10000, False
,
184 overlayVisualsAtom
, &actualType
, &actualFormat
,
185 &sizeData
, &bytesLeft
,
186 (unsigned char **) &overlay_info
);
188 if (status
!= Success
|| actualType
!= overlayVisualsAtom
||
189 actualFormat
!= 32 || sizeData
< 4) {
190 /* something went wrong */
191 XFree((void *) overlay_info
);
195 /* search the overlay visual list for the visual ID of interest */
196 numOverlaysPerScreen
= (int) (sizeData
/ 4);
197 for (i
=0;i
<numOverlaysPerScreen
;i
++) {
199 ov
= overlay_info
+ i
;
200 if (ov
->overlay_visual
==vinfo
->visualid
) {
201 /* found the visual */
202 if (/*ov->transparent_type==1 &&*/ ov
->layer
!=0) {
203 int level
= ov
->layer
;
204 XFree((void *) overlay_info
);
208 XFree((void *) overlay_info
);
214 /* The visual ID was not found in the overlay list. */
215 XFree((void *) overlay_info
);
223 * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
224 * configuration in our list of GLX visuals.
227 save_glx_visual( Display
*dpy
, XVisualInfo
*vinfo
,
228 GLboolean rgbFlag
, GLboolean alphaFlag
, GLboolean dbFlag
,
229 GLboolean stereoFlag
,
230 GLint depth_size
, GLint stencil_size
,
231 GLint accum_size
, GLint level
)
233 GLboolean ximageFlag
= GL_TRUE
;
236 GLboolean comparePointers
;
239 /* Check if the MESA_BACK_BUFFER env var is set */
240 char *backbuffer
= getenv("MESA_BACK_BUFFER");
242 if (backbuffer
[0]=='p' || backbuffer
[0]=='P') {
243 ximageFlag
= GL_FALSE
;
245 else if (backbuffer
[0]=='x' || backbuffer
[0]=='X') {
246 ximageFlag
= GL_TRUE
;
249 fprintf(stderr
, "Mesa: invalid value for MESA_BACK_BUFFER ");
250 fprintf(stderr
, "environment variable, using an XImage.\n");
255 /* Comparing IDs uses less memory but sometimes fails. */
256 /* XXX revisit this after 3.0 is finished. */
257 if (getenv("MESA_GLX_VISUAL_HACK"))
258 comparePointers
= GL_TRUE
;
260 comparePointers
= GL_FALSE
;
262 /* First check if a matching visual is already in the list */
263 for (i
=0; i
<NumVisuals
; i
++) {
264 XMesaVisual v
= VisualTable
[i
];
265 if (v
->display
== dpy
267 && v
->ximage_flag
== ximageFlag
268 && v
->gl_visual
->RGBAflag
== rgbFlag
269 && v
->gl_visual
->DBflag
== dbFlag
270 && v
->gl_visual
->StereoFlag
== stereoFlag
271 && (v
->gl_visual
->AlphaBits
> 0) == alphaFlag
272 && (v
->gl_visual
->DepthBits
>= depth_size
|| depth_size
== 0)
273 && (v
->gl_visual
->StencilBits
>= stencil_size
|| stencil_size
== 0)
274 && (v
->gl_visual
->AccumBits
>= accum_size
|| accum_size
== 0)) {
275 /* now either compare XVisualInfo pointers or visual IDs */
276 if ((!comparePointers
&& v
->visinfo
->visualid
== vinfo
->visualid
)
277 || (comparePointers
&& v
->vishandle
== vinfo
)) {
283 /* Create a new visual and add it to the list. */
285 if (NumVisuals
>=MAX_VISUALS
) {
286 fprintf( stderr
, "GLX Error: maximum number of visuals exceeded\n");
290 xmvis
= XMesaCreateVisual( dpy
, vinfo
, rgbFlag
, alphaFlag
, dbFlag
,
291 stereoFlag
, ximageFlag
,
292 depth_size
, stencil_size
, accum_size
, level
);
294 VisualTable
[NumVisuals
] = xmvis
;
303 * Create a GLX visual from a regular XVisualInfo.
304 * This is called when Fake GLX is given an XVisualInfo which wasn't
305 * returned by glXChooseVisual. Since this is the first time we're
306 * considering this visual we'll take a guess at reasonable values
307 * for depth buffer size, stencil size, accum size, etc.
308 * This is the best we can do with a client-side emulation of GLX.
311 create_glx_visual( Display
*dpy
, XVisualInfo
*visinfo
)
315 vislevel
= level_of_visual( dpy
, visinfo
);
317 /* Configure this visual as a CI, single-buffered overlay */
318 return save_glx_visual( dpy
, visinfo
,
320 GL_FALSE
, /* alpha */
321 GL_FALSE
, /* double */
322 GL_FALSE
, /* stereo */
324 0, /* stencil bits */
329 else if (is_usable_visual( visinfo
)) {
330 /* Configure this visual as RGB, double-buffered, depth-buffered. */
331 /* This is surely wrong for some people's needs but what else */
332 /* can be done? They should use glXChooseVisual(). */
333 return save_glx_visual( dpy
, visinfo
,
335 GL_FALSE
, /* alpha */
336 GL_TRUE
, /* double */
337 GL_FALSE
, /* stereo */
338 DEFAULT_SOFTWARE_DEPTH_BITS
,
339 8 * sizeof(GLstencil
),
345 fprintf(stderr
,"Mesa: error in glXCreateContext: bad visual\n");
353 * Find the GLX visual associated with an XVisualInfo.
356 find_glx_visual( Display
*dpy
, XVisualInfo
*vinfo
)
360 /* First try to match pointers */
361 for (i
=0;i
<NumVisuals
;i
++) {
362 if (VisualTable
[i
]->display
==dpy
&& VisualTable
[i
]->vishandle
==vinfo
) {
363 return VisualTable
[i
];
366 /* try to match visual id */
367 for (i
=0;i
<NumVisuals
;i
++) {
368 if (VisualTable
[i
]->display
==dpy
369 && VisualTable
[i
]->visinfo
->visualid
== vinfo
->visualid
) {
370 return VisualTable
[i
];
379 * Return the transparent pixel value for a GLX visual.
380 * Input: glxvis - the glx_visual
381 * Return: a pixel value or -1 if no transparent pixel
383 static int transparent_pixel( XMesaVisual glxvis
)
385 Display
*dpy
= glxvis
->display
;
386 XVisualInfo
*vinfo
= glxvis
->visinfo
;
387 Atom overlayVisualsAtom
;
388 OverlayInfo
*overlay_info
= NULL
;
389 int numOverlaysPerScreen
;
393 unsigned long sizeData
, bytesLeft
;
397 * The SERVER_OVERLAY_VISUALS property on the root window contains
398 * a list of overlay visuals. Get that list now.
400 overlayVisualsAtom
= XInternAtom(dpy
,"SERVER_OVERLAY_VISUALS", True
);
401 if (overlayVisualsAtom
== None
) {
405 status
= XGetWindowProperty(dpy
, RootWindow( dpy
, vinfo
->screen
),
406 overlayVisualsAtom
, 0L, (long) 10000, False
,
407 overlayVisualsAtom
, &actualType
, &actualFormat
,
408 &sizeData
, &bytesLeft
,
409 (unsigned char **) &overlay_info
);
411 if (status
!= Success
|| actualType
!= overlayVisualsAtom
||
412 actualFormat
!= 32 || sizeData
< 4) {
413 /* something went wrong */
414 XFree((void *) overlay_info
);
418 /* search the overlay visual list for the visual ID of interest */
419 numOverlaysPerScreen
= (int) (sizeData
/ 4);
420 for (i
=0;i
<numOverlaysPerScreen
;i
++) {
422 ov
= overlay_info
+ i
;
423 if (ov
->overlay_visual
==vinfo
->visualid
) {
425 if (ov
->transparent_type
==0) {
426 /* type 0 indicates no transparency */
427 XFree((void *) overlay_info
);
431 /* ov->value is the transparent pixel */
432 XFree((void *) overlay_info
);
438 /* The visual ID was not found in the overlay list. */
439 XFree((void *) overlay_info
);
446 * Return number of bits set in n.
448 static int bitcount( unsigned long n
)
451 for (bits
=0; n
>0; n
=n
>>1) {
461 * Try to get an X visual which matches the given arguments.
463 static XVisualInfo
*get_visual( Display
*dpy
, int scr
,
464 unsigned int depth
, int xclass
)
466 XVisualInfo temp
, *vis
;
469 unsigned int default_depth
;
472 mask
= VisualScreenMask
| VisualDepthMask
| VisualClassMask
;
477 default_depth
= DefaultDepth(dpy
,scr
);
478 default_class
= DefaultVisual(dpy
,scr
)->CLASS
;
480 if (depth
==default_depth
&& xclass
==default_class
) {
481 /* try to get root window's visual */
482 temp
.visualid
= DefaultVisual(dpy
,scr
)->visualid
;
483 mask
|= VisualIDMask
;
486 vis
= XGetVisualInfo( dpy
, mask
, &temp
, &n
);
488 /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
489 * An SGI Infinite Reality system, for example, can have 30bpp pixels:
490 * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel.
492 if (vis
&& depth
> 24 && (xclass
==TrueColor
|| xclass
==DirectColor
)) {
493 if (bitcount(vis
->red_mask
) <= 8
494 && bitcount(vis
->green_mask
) <= 8
495 && bitcount(vis
->blue_mask
) <= 8) {
510 * Retrieve the value of the given environment variable and find
511 * the X visual which matches it.
512 * Input: dpy - the display
513 * screen - the screen number
514 * varname - the name of the environment variable
515 * Return: an XVisualInfo pointer to NULL if error.
517 static XVisualInfo
*get_env_visual(Display
*dpy
, int scr
, const char *varname
)
519 char value
[100], type
[100];
520 int depth
, xclass
= -1;
523 if (!getenv( varname
)) {
527 strncpy( value
, getenv(varname
), 100 );
530 sscanf( value
, "%s %d", type
, &depth
);
532 if (strcmp(type
,"TrueColor")==0) xclass
= TrueColor
;
533 else if (strcmp(type
,"DirectColor")==0) xclass
= DirectColor
;
534 else if (strcmp(type
,"PseudoColor")==0) xclass
= PseudoColor
;
535 else if (strcmp(type
,"StaticColor")==0) xclass
= StaticColor
;
536 else if (strcmp(type
,"GrayScale")==0) xclass
= GrayScale
;
537 else if (strcmp(type
,"StaticGray")==0) xclass
= StaticGray
;
539 if (xclass
>-1 && depth
>0) {
540 vis
= get_visual( dpy
, scr
, depth
, xclass
);
546 fprintf( stderr
, "Mesa: GLX unable to find visual class=%s, depth=%d.\n",
554 * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
555 * Input: dpy, screen - X display and screen number
556 * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
557 * min_depth - minimum visual depth
558 * preferred_class - preferred GLX visual class or DONT_CARE
559 * Return: pointer to an XVisualInfo or NULL.
561 static XVisualInfo
*choose_x_visual( Display
*dpy
, int screen
,
562 GLboolean rgba
, int min_depth
,
563 int preferred_class
)
566 int xclass
, visclass
;
570 Atom hp_cr_maps
= XInternAtom(dpy
, "_HP_RGB_SMOOTH_MAP_LIST", True
);
571 /* First see if the MESA_RGB_VISUAL env var is defined */
572 vis
= get_env_visual( dpy
, screen
, "MESA_RGB_VISUAL" );
576 /* Otherwise, search for a suitable visual */
577 if (preferred_class
==DONT_CARE
) {
578 for (xclass
=0;xclass
<6;xclass
++) {
580 case 0: visclass
= TrueColor
; break;
581 case 1: visclass
= DirectColor
; break;
582 case 2: visclass
= PseudoColor
; break;
583 case 3: visclass
= StaticColor
; break;
584 case 4: visclass
= GrayScale
; break;
585 case 5: visclass
= StaticGray
; break;
588 /* start with shallowest */
589 for (depth
=0;depth
<=32;depth
++) {
590 if (visclass
==TrueColor
&& depth
==8 && !hp_cr_maps
) {
591 /* Special case: try to get 8-bit PseudoColor before */
592 /* 8-bit TrueColor */
593 vis
= get_visual( dpy
, screen
, 8, PseudoColor
);
598 vis
= get_visual( dpy
, screen
, depth
, visclass
);
605 /* start with deepest */
606 for (depth
=32;depth
>=min_depth
;depth
--) {
607 if (visclass
==TrueColor
&& depth
==8 && !hp_cr_maps
) {
608 /* Special case: try to get 8-bit PseudoColor before */
609 /* 8-bit TrueColor */
610 vis
= get_visual( dpy
, screen
, 8, PseudoColor
);
615 vis
= get_visual( dpy
, screen
, depth
, visclass
);
624 /* search for a specific visual class */
625 switch (preferred_class
) {
626 case GLX_TRUE_COLOR_EXT
: visclass
= TrueColor
; break;
627 case GLX_DIRECT_COLOR_EXT
: visclass
= DirectColor
; break;
628 case GLX_PSEUDO_COLOR_EXT
: visclass
= PseudoColor
; break;
629 case GLX_STATIC_COLOR_EXT
: visclass
= StaticColor
; break;
630 case GLX_GRAY_SCALE_EXT
: visclass
= GrayScale
; break;
631 case GLX_STATIC_GRAY_EXT
: visclass
= StaticGray
; break;
632 default: return NULL
;
635 /* start with shallowest */
636 for (depth
=0;depth
<=32;depth
++) {
637 vis
= get_visual( dpy
, screen
, depth
, visclass
);
644 /* start with deepest */
645 for (depth
=32;depth
>=min_depth
;depth
--) {
646 vis
= get_visual( dpy
, screen
, depth
, visclass
);
655 /* First see if the MESA_CI_VISUAL env var is defined */
656 vis
= get_env_visual( dpy
, screen
, "MESA_CI_VISUAL" );
660 /* Otherwise, search for a suitable visual, starting with shallowest */
661 if (preferred_class
==DONT_CARE
) {
662 for (xclass
=0;xclass
<4;xclass
++) {
664 case 0: visclass
= PseudoColor
; break;
665 case 1: visclass
= StaticColor
; break;
666 case 2: visclass
= GrayScale
; break;
667 case 3: visclass
= StaticGray
; break;
669 /* try 8-bit up through 16-bit */
670 for (depth
=8;depth
<=16;depth
++) {
671 vis
= get_visual( dpy
, screen
, depth
, visclass
);
676 /* try min_depth up to 8-bit */
677 for (depth
=min_depth
;depth
<8;depth
++) {
678 vis
= get_visual( dpy
, screen
, depth
, visclass
);
686 /* search for a specific visual class */
687 switch (preferred_class
) {
688 case GLX_TRUE_COLOR_EXT
: visclass
= TrueColor
; break;
689 case GLX_DIRECT_COLOR_EXT
: visclass
= DirectColor
; break;
690 case GLX_PSEUDO_COLOR_EXT
: visclass
= PseudoColor
; break;
691 case GLX_STATIC_COLOR_EXT
: visclass
= StaticColor
; break;
692 case GLX_GRAY_SCALE_EXT
: visclass
= GrayScale
; break;
693 case GLX_STATIC_GRAY_EXT
: visclass
= StaticGray
; break;
694 default: return NULL
;
696 /* try 8-bit up through 16-bit */
697 for (depth
=8;depth
<=16;depth
++) {
698 vis
= get_visual( dpy
, screen
, depth
, visclass
);
703 /* try min_depth up to 8-bit */
704 for (depth
=min_depth
;depth
<8;depth
++) {
705 vis
= get_visual( dpy
, screen
, depth
, visclass
);
713 /* didn't find a visual */
720 * Find the deepest X over/underlay visual of at least min_depth.
721 * Input: dpy, screen - X display and screen number
722 * level - the over/underlay level
723 * trans_type - transparent pixel type: GLX_NONE_EXT,
724 * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
726 * trans_value - transparent pixel value or DONT_CARE
727 * min_depth - minimum visual depth
728 * preferred_class - preferred GLX visual class or DONT_CARE
729 * Return: pointer to an XVisualInfo or NULL.
731 static XVisualInfo
*choose_x_overlay_visual( Display
*dpy
, int scr
,
733 int level
, int trans_type
,
736 int preferred_class
)
738 Atom overlayVisualsAtom
;
739 OverlayInfo
*overlay_info
;
740 int numOverlaysPerScreen
;
744 unsigned long sizeData
, bytesLeft
;
746 XVisualInfo
*deepvis
;
749 /*DEBUG int tt, tv; */
751 switch (preferred_class
) {
752 case GLX_TRUE_COLOR_EXT
: preferred_class
= TrueColor
; break;
753 case GLX_DIRECT_COLOR_EXT
: preferred_class
= DirectColor
; break;
754 case GLX_PSEUDO_COLOR_EXT
: preferred_class
= PseudoColor
; break;
755 case GLX_STATIC_COLOR_EXT
: preferred_class
= StaticColor
; break;
756 case GLX_GRAY_SCALE_EXT
: preferred_class
= GrayScale
; break;
757 case GLX_STATIC_GRAY_EXT
: preferred_class
= StaticGray
; break;
758 default: preferred_class
= DONT_CARE
;
762 * The SERVER_OVERLAY_VISUALS property on the root window contains
763 * a list of overlay visuals. Get that list now.
765 overlayVisualsAtom
= XInternAtom(dpy
,"SERVER_OVERLAY_VISUALS", True
);
766 if (overlayVisualsAtom
== (Atom
) None
) {
770 status
= XGetWindowProperty(dpy
, RootWindow( dpy
, scr
),
771 overlayVisualsAtom
, 0L, (long) 10000, False
,
772 overlayVisualsAtom
, &actualType
, &actualFormat
,
773 &sizeData
, &bytesLeft
,
774 (unsigned char **) &overlay_info
);
776 if (status
!= Success
|| actualType
!= overlayVisualsAtom
||
777 actualFormat
!= 32 || sizeData
< 4) {
778 /* something went wrong */
782 /* Search for the deepest overlay which satisifies all criteria. */
786 numOverlaysPerScreen
= (int) (sizeData
/ 4);
787 for (i
=0;i
<numOverlaysPerScreen
;i
++) {
788 XVisualInfo
*vislist
, vistemplate
;
791 ov
= overlay_info
+ i
;
793 if (ov
->layer
!=level
) {
794 /* failed overlay level criteria */
797 if (!(trans_type
==DONT_CARE
798 || (trans_type
==GLX_TRANSPARENT_INDEX_EXT
799 && ov
->transparent_type
>0)
800 || (trans_type
==GLX_NONE_EXT
&& ov
->transparent_type
==0))) {
801 /* failed transparent pixel type criteria */
804 if (trans_value
!=DONT_CARE
&& trans_value
!=ov
->value
) {
805 /* failed transparent pixel value criteria */
809 /* get XVisualInfo and check the depth */
810 vistemplate
.visualid
= ov
->overlay_visual
;
811 vistemplate
.screen
= scr
;
812 vislist
= XGetVisualInfo( dpy
, VisualIDMask
| VisualScreenMask
,
813 &vistemplate
, &count
);
816 /* something went wrong */
819 if (preferred_class
!=DONT_CARE
&& preferred_class
!=vislist
->CLASS
) {
820 /* wrong visual class */
824 /* if RGB was requested, make sure we have True/DirectColor */
825 if (rgbFlag
&& vislist
->CLASS
!= TrueColor
826 && vislist
->CLASS
!= DirectColor
)
829 /* if CI was requested, make sure we have a color indexed visual */
831 && (vislist
->CLASS
== TrueColor
|| vislist
->CLASS
== DirectColor
))
834 if (deepvis
==NULL
|| vislist
->depth
> deepest
) {
835 /* YES! found a satisfactory visual */
839 deepest
= vislist
->depth
;
841 /* DEBUG tt = ov->transparent_type;*/
842 /* DEBUG tv = ov->value; */
848 printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n",
849 deepvis->visualid, level, deepvis->depth, tt, tv );
858 Fake_glXChooseVisual( Display
*dpy
, int screen
, int *list
)
863 int min_red
=0, min_green
=0, min_blue
=0;
864 GLboolean rgb_flag
= GL_FALSE
;
865 GLboolean alpha_flag
= GL_FALSE
;
866 GLboolean double_flag
= GL_FALSE
;
867 GLboolean stereo_flag
= GL_FALSE
;
868 GLint depth_size
= 0;
869 GLint stencil_size
= 0;
870 GLint accum_size
= 0;
872 int visual_type
= DONT_CARE
;
873 int trans_type
= DONT_CARE
;
874 int trans_value
= DONT_CARE
;
880 switch (*parselist
) {
885 case GLX_BUFFER_SIZE
:
887 min_ci
= *parselist
++;
891 level
= *parselist
++;
897 case GLX_DOUBLEBUFFER
:
898 double_flag
= GL_TRUE
;
902 stereo_flag
= GL_TRUE
;
904 case GLX_AUX_BUFFERS
:
911 min_red
= *parselist
++;
915 min_green
= *parselist
++;
919 min_blue
= *parselist
++;
924 GLint size
= *parselist
++;
925 alpha_flag
= size
>0 ? 1 : 0;
930 depth_size
= *parselist
++;
932 case GLX_STENCIL_SIZE
:
934 stencil_size
= *parselist
++;
936 case GLX_ACCUM_RED_SIZE
:
937 case GLX_ACCUM_GREEN_SIZE
:
938 case GLX_ACCUM_BLUE_SIZE
:
939 case GLX_ACCUM_ALPHA_SIZE
:
942 GLint size
= *parselist
++;
943 accum_size
= MAX2( accum_size
, size
);
948 * GLX_EXT_visual_info extension
950 case GLX_X_VISUAL_TYPE_EXT
:
952 visual_type
= *parselist
++;
954 case GLX_TRANSPARENT_TYPE_EXT
:
956 trans_type
= *parselist
++;
958 case GLX_TRANSPARENT_INDEX_VALUE_EXT
:
960 trans_value
= *parselist
++;
962 case GLX_TRANSPARENT_RED_VALUE_EXT
:
963 case GLX_TRANSPARENT_GREEN_VALUE_EXT
:
964 case GLX_TRANSPARENT_BLUE_VALUE_EXT
:
965 case GLX_TRANSPARENT_ALPHA_VALUE_EXT
:
974 /* undefined attribute */
980 * Since we're only simulating the GLX extension this function will never
981 * find any real GL visuals. Instead, all we can do is try to find an RGB
982 * or CI visual of appropriate depth. Other requested attributes such as
983 * double buffering, depth buffer, etc. will be associated with the X
984 * visual and stored in the VisualTable[].
987 /* normal color planes */
989 /* Get an RGB visual */
990 int min_rgb
= min_red
+ min_green
+ min_blue
;
991 if (min_rgb
>1 && min_rgb
<8) {
992 /* a special case to be sure we can get a monochrome visual */
995 vis
= choose_x_visual( dpy
, screen
, rgb_flag
, min_rgb
, visual_type
);
998 /* Get a color index visual */
999 vis
= choose_x_visual( dpy
, screen
, rgb_flag
, min_ci
, visual_type
);
1004 /* over/underlay planes */
1007 int min_rgb
= min_red
+ min_green
+ min_blue
;
1008 if (min_rgb
>1 && min_rgb
<8) {
1009 /* a special case to be sure we can get a monochrome visual */
1012 vis
= choose_x_overlay_visual( dpy
, screen
, rgb_flag
, level
,
1013 trans_type
, trans_value
, min_rgb
, visual_type
);
1016 /* color index overlay */
1017 vis
= choose_x_overlay_visual( dpy
, screen
, rgb_flag
, level
,
1018 trans_type
, trans_value
, min_ci
, visual_type
);
1023 /* Note: we're not exactly obeying the glXChooseVisual rules here.
1024 * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
1025 * largest depth buffer size, which is 32bits/value. However, we
1026 * return 16 to maintain performance with earlier versions of Mesa.
1028 if (depth_size
== 1)
1029 depth_size
= DEFAULT_SOFTWARE_DEPTH_BITS
;
1030 else if (depth_size
> 24)
1032 else if (depth_size
> 16)
1034 /* we only support one size of stencil and accum buffers. */
1035 if (stencil_size
> 0)
1036 stencil_size
= STENCIL_BITS
;
1038 accum_size
= ACCUM_BITS
;
1039 if (!save_glx_visual( dpy
, vis
, rgb_flag
, alpha_flag
, double_flag
,
1041 depth_size
, stencil_size
, accum_size
, level
))
1052 Fake_glXCreateContext( Display
*dpy
, XVisualInfo
*visinfo
,
1053 GLXContext share_list
, Bool direct
)
1058 /* deallocate unused windows/buffers */
1059 XMesaGarbageCollect();
1061 glxvis
= find_glx_visual( dpy
, visinfo
);
1063 /* This visual wasn't found with glXChooseVisual() */
1064 glxvis
= create_glx_visual( dpy
, visinfo
);
1066 /* unusable visual */
1071 xmctx
= XMesaCreateContext( glxvis
, (XMesaContext
) share_list
);
1073 /* set the direct/indirect flag */
1074 xmctx
->direct
= direct
;
1076 return (GLXContext
) xmctx
;
1080 static GLXContext MakeCurrent_PrevContext
= 0;
1081 static GLXDrawable MakeCurrent_PrevDrawable
= 0;
1082 static GLXDrawable MakeCurrent_PrevReadable
= 0;
1083 static XMesaBuffer MakeCurrent_PrevDrawBuffer
= 0;
1084 static XMesaBuffer MakeCurrent_PrevReadBuffer
= 0;
1086 /* GLX 1.3 and later */
1088 Fake_glXMakeContextCurrent( Display
*dpy
, GLXDrawable draw
,
1089 GLXDrawable read
, GLXContext ctx
)
1091 if (ctx
&& draw
&& read
) {
1092 XMesaBuffer drawBuffer
, readBuffer
;
1093 XMesaContext xmctx
= (XMesaContext
) ctx
;
1095 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
1096 if (ctx
== MakeCurrent_PrevContext
1097 && draw
== MakeCurrent_PrevDrawable
) {
1098 drawBuffer
= MakeCurrent_PrevDrawBuffer
;
1101 drawBuffer
= XMesaFindBuffer( dpy
, draw
);
1104 /* drawable must be a new window! */
1105 drawBuffer
= XMesaCreateWindowBuffer2( xmctx
->xm_visual
, draw
, ctx
);
1107 /* Out of memory, or context/drawable depth mismatch */
1112 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
1113 if (ctx
== MakeCurrent_PrevContext
1114 && read
== MakeCurrent_PrevReadable
) {
1115 readBuffer
= MakeCurrent_PrevReadBuffer
;
1118 readBuffer
= XMesaFindBuffer( dpy
, read
);
1121 /* drawable must be a new window! */
1122 readBuffer
= XMesaCreateWindowBuffer2( xmctx
->xm_visual
, read
, ctx
);
1124 /* Out of memory, or context/drawable depth mismatch */
1129 MakeCurrent_PrevContext
= ctx
;
1130 MakeCurrent_PrevDrawable
= draw
;
1131 MakeCurrent_PrevReadable
= read
;
1132 MakeCurrent_PrevDrawBuffer
= drawBuffer
;
1133 MakeCurrent_PrevReadBuffer
= readBuffer
;
1135 /* Now make current! */
1136 return (Bool
) XMesaMakeCurrent2((XMesaContext
) ctx
, drawBuffer
, readBuffer
);
1138 else if (!ctx
&& !draw
&& !read
) {
1139 /* release current context w/out assigning new one. */
1140 XMesaMakeCurrent( NULL
, NULL
);
1141 MakeCurrent_PrevContext
= 0;
1142 MakeCurrent_PrevDrawable
= 0;
1143 MakeCurrent_PrevReadable
= 0;
1144 MakeCurrent_PrevDrawBuffer
= 0;
1145 MakeCurrent_PrevReadBuffer
= 0;
1149 /* The args must either all be non-zero or all zero.
1159 Fake_glXMakeCurrent( Display
*dpy
, GLXDrawable drawable
, GLXContext ctx
)
1161 return Fake_glXMakeContextCurrent( dpy
, drawable
, drawable
, ctx
);
1167 Fake_glXCreateGLXPixmap( Display
*dpy
, XVisualInfo
*visinfo
, Pixmap pixmap
)
1172 v
= find_glx_visual( dpy
, visinfo
);
1174 v
= create_glx_visual( dpy
, visinfo
);
1176 /* unusable visual */
1181 b
= XMesaCreatePixmapBuffer( v
, pixmap
, 0 );
1185 return b
->frontbuffer
;
1189 #ifdef GLX_MESA_pixmap_colormap
1192 Fake_glXCreateGLXPixmapMESA( Display
*dpy
, XVisualInfo
*visinfo
,
1193 Pixmap pixmap
, Colormap cmap
)
1198 v
= find_glx_visual( dpy
, visinfo
);
1200 v
= create_glx_visual( dpy
, visinfo
);
1202 /* unusable visual */
1207 b
= XMesaCreatePixmapBuffer( v
, pixmap
, cmap
);
1211 return b
->frontbuffer
;
1218 Fake_glXDestroyGLXPixmap( Display
*dpy
, GLXPixmap pixmap
)
1220 XMesaBuffer b
= XMesaFindBuffer(dpy
, pixmap
);
1222 XMesaDestroyBuffer(b
);
1224 else if (getenv("MESA_DEBUG")) {
1225 fprintf( stderr
, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
1231 Fake_glXCopyContext( Display
*dpy
, GLXContext src
, GLXContext dst
,
1232 unsigned long mask
)
1234 XMesaContext xm_src
= (XMesaContext
) src
;
1235 XMesaContext xm_dst
= (XMesaContext
) dst
;
1237 gl_copy_context( xm_src
->gl_ctx
, xm_dst
->gl_ctx
, (GLuint
) mask
);
1243 Fake_glXQueryExtension( Display
*dpy
, int *errorb
, int *event
)
1245 /* Mesa's GLX isn't really an X extension but we try to act like one. */
1253 extern void _kw_ungrab_all( Display
*dpy
);
1254 void _kw_ungrab_all( Display
*dpy
)
1256 XUngrabPointer( dpy
, CurrentTime
);
1257 XUngrabKeyboard( dpy
, CurrentTime
);
1262 Fake_glXDestroyContext( Display
*dpy
, GLXContext ctx
)
1265 MakeCurrent_PrevContext
= 0;
1266 MakeCurrent_PrevDrawable
= 0;
1267 MakeCurrent_PrevReadable
= 0;
1268 MakeCurrent_PrevDrawBuffer
= 0;
1269 MakeCurrent_PrevReadBuffer
= 0;
1270 XMesaDestroyContext( (XMesaContext
) ctx
);
1271 XMesaGarbageCollect();
1277 Fake_glXIsDirect( Display
*dpy
, GLXContext ctx
)
1280 return ((XMesaContext
) ctx
)->direct
;
1286 Fake_glXSwapBuffers( Display
*dpy
, GLXDrawable drawable
)
1288 XMesaBuffer buffer
= XMesaFindBuffer( dpy
, drawable
);
1291 XMesaSwapBuffers(buffer
);
1293 else if (getenv("MESA_DEBUG")) {
1294 fprintf(stderr
, "Mesa Warning: glXSwapBuffers: invalid drawable\n");
1300 Fake_glXCopySubBufferMESA( Display
*dpy
, GLXDrawable drawable
,
1301 int x
, int y
, int width
, int height
)
1303 XMesaBuffer buffer
= XMesaFindBuffer( dpy
, drawable
);
1305 XMesaCopySubBuffer(buffer
, x
, y
, width
, height
);
1307 else if (getenv("MESA_DEBUG")) {
1308 fprintf(stderr
, "Mesa Warning: glXCopySubBufferMESA: invalid drawable\n");
1315 Fake_glXQueryVersion( Display
*dpy
, int *maj
, int *min
)
1318 /* Return GLX version, not Mesa version */
1319 assert(CLIENT_MAJOR_VERSION
== SERVER_MAJOR_VERSION
);
1320 *maj
= CLIENT_MAJOR_VERSION
;
1321 *min
= MIN2( CLIENT_MINOR_VERSION
, SERVER_MINOR_VERSION
);
1328 * Query the GLX attributes of the given XVisualInfo.
1331 Fake_glXGetConfig( Display
*dpy
, XVisualInfo
*visinfo
,
1332 int attrib
, int *value
)
1336 glxvis
= find_glx_visual( dpy
, visinfo
);
1338 /* this visual wasn't obtained with glXChooseVisual */
1339 glxvis
= create_glx_visual( dpy
, visinfo
);
1341 /* this visual can't be used for GL rendering */
1342 if (attrib
==GLX_USE_GL
) {
1343 *value
= (int) False
;
1347 /*fprintf( stderr, "Mesa: Error in glXGetConfig: bad visual\n");*/
1348 return GLX_BAD_VISUAL
;
1355 *value
= (int) True
;
1357 case GLX_BUFFER_SIZE
:
1358 *value
= visinfo
->depth
;
1361 *value
= glxvis
->level
;
1364 if (glxvis
->gl_visual
->RGBAflag
) {
1371 case GLX_DOUBLEBUFFER
:
1372 *value
= (int) glxvis
->gl_visual
->DBflag
;
1375 *value
= (int) glxvis
->gl_visual
->StereoFlag
;
1377 case GLX_AUX_BUFFERS
:
1378 *value
= (int) False
;
1381 *value
= glxvis
->gl_visual
->RedBits
;
1383 case GLX_GREEN_SIZE
:
1384 *value
= glxvis
->gl_visual
->GreenBits
;
1387 *value
= glxvis
->gl_visual
->BlueBits
;
1389 case GLX_ALPHA_SIZE
:
1390 *value
= glxvis
->gl_visual
->AlphaBits
;
1392 case GLX_DEPTH_SIZE
:
1393 *value
= glxvis
->gl_visual
->DepthBits
;
1395 case GLX_STENCIL_SIZE
:
1396 *value
= glxvis
->gl_visual
->StencilBits
;
1398 case GLX_ACCUM_RED_SIZE
:
1399 case GLX_ACCUM_GREEN_SIZE
:
1400 case GLX_ACCUM_BLUE_SIZE
:
1401 *value
= glxvis
->gl_visual
->AccumBits
;
1403 case GLX_ACCUM_ALPHA_SIZE
:
1404 if (glxvis
->gl_visual
->AlphaBits
> 0)
1405 *value
= glxvis
->gl_visual
->AccumBits
;
1411 * GLX_EXT_visual_info extension
1413 case GLX_X_VISUAL_TYPE_EXT
:
1414 switch (glxvis
->visinfo
->CLASS
) {
1415 case StaticGray
: *value
= GLX_STATIC_GRAY_EXT
; return 0;
1416 case GrayScale
: *value
= GLX_GRAY_SCALE_EXT
; return 0;
1417 case StaticColor
: *value
= GLX_STATIC_GRAY_EXT
; return 0;
1418 case PseudoColor
: *value
= GLX_PSEUDO_COLOR_EXT
; return 0;
1419 case TrueColor
: *value
= GLX_TRUE_COLOR_EXT
; return 0;
1420 case DirectColor
: *value
= GLX_DIRECT_COLOR_EXT
; return 0;
1423 case GLX_TRANSPARENT_TYPE_EXT
:
1424 if (glxvis
->level
==0) {
1426 *value
= GLX_NONE_EXT
;
1428 else if (glxvis
->level
>0) {
1430 if (glxvis
->gl_visual
->RGBAflag
) {
1431 *value
= GLX_TRANSPARENT_RGB_EXT
;
1434 *value
= GLX_TRANSPARENT_INDEX_EXT
;
1437 else if (glxvis
->level
<0) {
1439 *value
= GLX_NONE_EXT
;
1442 case GLX_TRANSPARENT_INDEX_VALUE_EXT
:
1444 int pixel
= transparent_pixel( glxvis
);
1448 /* else undefined */
1451 case GLX_TRANSPARENT_RED_VALUE_EXT
:
1454 case GLX_TRANSPARENT_GREEN_VALUE_EXT
:
1457 case GLX_TRANSPARENT_BLUE_VALUE_EXT
:
1460 case GLX_TRANSPARENT_ALPHA_VALUE_EXT
:
1468 return GLX_BAD_ATTRIBUTE
;
1475 Fake_glXWaitGL( void )
1477 XMesaContext xmesa
= XMesaGetCurrentContext();
1478 XMesaFlush( xmesa
);
1484 Fake_glXWaitX( void )
1486 XMesaContext xmesa
= XMesaGetCurrentContext();
1487 XMesaFlush( xmesa
);
1492 * Return the extensions string, which is 3Dfx-dependant.
1494 static const char *get_extensions( void )
1497 const char *fx
= getenv("MESA_GLX_FX");
1498 if (fx
&& fx
[0] != 'd') {
1499 return "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync GLX_MESA_set_3dfx_mode GLX_ARB_get_proc_address";
1502 return "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync GLX_ARB_get_proc_address";
1507 /* GLX 1.1 and later */
1509 Fake_glXQueryExtensionsString( Display
*dpy
, int screen
)
1513 return get_extensions();
1518 /* GLX 1.1 and later */
1520 Fake_glXQueryServerString( Display
*dpy
, int screen
, int name
)
1522 static char version
[1000];
1523 sprintf(version
, "%d.%d %s", SERVER_MAJOR_VERSION
, SERVER_MINOR_VERSION
,
1530 case GLX_EXTENSIONS
:
1531 return get_extensions();
1543 /* GLX 1.1 and later */
1545 Fake_glXGetClientString( Display
*dpy
, int name
)
1547 static char version
[1000];
1548 sprintf(version
, "%d.%d %s", CLIENT_MAJOR_VERSION
, CLIENT_MINOR_VERSION
,
1554 case GLX_EXTENSIONS
:
1555 return get_extensions();
1572 Fake_glXChooseFBConfig( Display
*dpy
, int screen
,
1573 const int *attribList
, int *nitems
)
1584 Fake_glXGetFBConfigAttrib( Display
*dpy
, GLXFBConfig config
,
1585 int attribute
, int *value
)
1595 static XVisualInfo
*
1596 Fake_glXGetVisualFromFBConfig( Display
*dpy
, GLXFBConfig config
)
1605 Fake_glXCreateWindow( Display
*dpy
, GLXFBConfig config
, Window win
,
1606 const int *attribList
)
1617 Fake_glXDestroyWindow( Display
*dpy
, GLXWindow window
)
1626 Fake_glXCreatePixmap( Display
*dpy
, GLXFBConfig config
, Pixmap pixmap
,
1627 const int *attribList
)
1638 Fake_glXDestroyPixmap( Display
*dpy
, GLXPixmap pixmap
)
1647 Fake_glXCreatePbuffer( Display
*dpy
, GLXFBConfig config
,
1648 const int *attribList
)
1658 Fake_glXDestroyPbuffer( Display
*dpy
, GLXPbuffer pbuf
)
1666 Fake_glXQueryDrawable( Display
*dpy
, GLXDrawable draw
, int attribute
,
1667 unsigned int *value
)
1677 Fake_glXCreateNewContext( Display
*dpy
, GLXFBConfig config
,
1678 int renderType
, GLXContext shareList
, Bool direct
)
1690 Fake_glXQueryContext( Display
*dpy
, GLXContext ctx
, int attribute
, int *value
)
1701 Fake_glXSelectEvent( Display
*dpy
, GLXDrawable drawable
, unsigned long mask
)
1710 Fake_glXGetSelectedEvent( Display
*dpy
, GLXDrawable drawable
,
1711 unsigned long *mask
)
1721 * Release the depth, stencil, accum buffers attached to a GLXDrawable
1722 * (a window or pixmap) prior to destroying the GLXDrawable.
1725 Fake_glXReleaseBuffersMESA( Display
*dpy
, GLXDrawable d
)
1727 XMesaBuffer b
= XMesaFindBuffer(dpy
, d
);
1729 XMesaDestroyBuffer(b
);
1737 * GLX_MESA_set_3dfx_mode
1740 Fake_glXSet3DfxModeMESA( GLint mode
)
1742 return XMesaSetFXmode( mode
);
1747 * GLX_SGI_video_sync
1750 #ifdef GLX_SGI_video_sync
1753 Fake_glXGetVideoSyncSGI(unsigned int *count
)
1760 Fake_glXWaitVideoSyncSGI(int divisor
, int remainder
, unsigned int *count
)
1769 extern void Fake_glXUseXFont( Font font
, int first
, int count
, int listbase
);
1772 extern struct _glxapi_table
*_mesa_GetGLXDispatchTable(void);
1773 struct _glxapi_table
*_mesa_GetGLXDispatchTable(void)
1775 static struct _glxapi_table glx
;
1777 /* be sure our dispatch table size <= libGL's table */
1779 int size
= sizeof(struct _glxapi_table
) / sizeof(void *);
1781 assert(_glxapi_get_dispatch_table_size() >= size
);
1784 /* initialize the whole table to no-ops */
1785 _glxapi_set_no_op_table(&glx
);
1787 /* now initialize the table with the functions I implement */
1788 glx
.ChooseVisual
= Fake_glXChooseVisual
;
1789 glx
.CopyContext
= Fake_glXCopyContext
;
1790 glx
.CreateContext
= Fake_glXCreateContext
;
1791 glx
.CreateGLXPixmap
= Fake_glXCreateGLXPixmap
;
1792 glx
.DestroyContext
= Fake_glXDestroyContext
;
1793 glx
.DestroyGLXPixmap
= Fake_glXDestroyGLXPixmap
;
1794 glx
.GetConfig
= Fake_glXGetConfig
;
1795 /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/
1796 /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/
1797 glx
.IsDirect
= Fake_glXIsDirect
;
1798 glx
.MakeCurrent
= Fake_glXMakeCurrent
;
1799 glx
.QueryExtension
= Fake_glXQueryExtension
;
1800 glx
.QueryVersion
= Fake_glXQueryVersion
;
1801 glx
.SwapBuffers
= Fake_glXSwapBuffers
;
1802 glx
.UseXFont
= Fake_glXUseXFont
;
1803 glx
.WaitGL
= Fake_glXWaitGL
;
1804 glx
.WaitX
= Fake_glXWaitX
;
1806 #ifdef _GLXAPI_VERSION_1_1
1807 glx
.GetClientString
= Fake_glXGetClientString
;
1808 glx
.QueryExtensionsString
= Fake_glXQueryExtensionsString
;
1809 glx
.QueryServerString
= Fake_glXQueryServerString
;
1812 #ifdef _GLXAPI_VERSION_1_2
1813 /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/
1816 #ifdef _GLXAPI_VERSION_1_3
1817 glx
.ChooseFBConfig
= Fake_glXChooseFBConfig
;
1818 glx
.CreateNewContext
= Fake_glXCreateNewContext
;
1819 glx
.CreatePbuffer
= Fake_glXCreatePbuffer
;
1820 glx
.CreatePixmap
= Fake_glXCreatePixmap
;
1821 glx
.CreateWindow
= Fake_glXCreateWindow
;
1822 glx
.DestroyPbuffer
= Fake_glXDestroyPbuffer
;
1823 glx
.DestroyPixmap
= Fake_glXDestroyPixmap
;
1824 glx
.DestroyWindow
= Fake_glXDestroyWindow
;
1825 /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/
1826 glx
.GetFBConfigAttrib
= Fake_glXGetFBConfigAttrib
;
1827 glx
.GetSelectedEvent
= Fake_glXGetSelectedEvent
;
1828 glx
.GetVisualFromFBConfig
= Fake_glXGetVisualFromFBConfig
;
1829 glx
.MakeContextCurrent
= Fake_glXMakeContextCurrent
;
1830 glx
.QueryContext
= Fake_glXQueryContext
;
1831 glx
.QueryDrawable
= Fake_glXQueryDrawable
;
1832 glx
.SelectEvent
= Fake_glXSelectEvent
;
1835 #ifdef _GLXAPI_SGI_video_sync
1836 glx
.GetVideoSyncSGI
= Fake_glXGetVideoSyncSGI
;
1837 glx
.WaitVideoSyncSGI
= Fake_glXWaitVideoSyncSGI
;
1840 #ifdef _GLXAPI_MESA_copy_sub_buffer
1841 glx
.CopySubBufferMESA
= Fake_glXCopySubBufferMESA
;
1844 #ifdef _GLXAPI_MESA_release_buffers
1845 glx
.ReleaseBuffersMESA
= Fake_glXReleaseBuffersMESA
;
1848 #ifdef _GLXAPI_MESA_pixmap_colormap
1849 glx
.CreateGLXPixmapMESA
= Fake_glXCreateGLXPixmapMESA
;
1852 #ifdef _GLXAPI_MESA_set_3dfx_mode
1853 glx
.Set3DfxModeMESA
= Fake_glXSet3DfxModeMESA
;