Replaced struct gl_visual with struct __GLcontextModesRec from glcore.h.
[mesa.git] / src / mesa / drivers / x11 / fakeglx.c
1 /* $Id: fakeglx.c,v 1.45 2001/01/23 23:39:37 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 /*
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.
31 *
32 * Thanks to the contributors:
33 *
34 * Initial version: Philip Brown (phil@bolthole.com)
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).
38 *
39 * Notes:
40 * Don't be fooled, stereo isn't supported yet.
41 */
42
43
44
45 #include "glxheader.h"
46 #include "glxapi.h"
47 #include "GL/xmesa.h"
48 #include "context.h"
49 #include "config.h"
50 #include "macros.h"
51 #include "mmath.h"
52 #include "mtypes.h"
53 #include "xfonts.h"
54 #include "xmesaP.h"
55
56
57 /* This indicates the client-side GLX API and GLX encoder version. */
58 #define CLIENT_MAJOR_VERSION 1
59 #define CLIENT_MINOR_VERSION 2
60
61 /* This indicates the server-side GLX decoder version.
62 * GLX 1.3 indicates OpenGL 1.2 support
63 */
64 #define SERVER_MAJOR_VERSION 1
65 #define SERVER_MINOR_VERSION 3
66
67 /* This is appended onto the glXGetClient/ServerString version strings. */
68 #define MESA_GLX_VERSION "Mesa 3.5"
69
70 /* Who implemented this GLX? */
71 #define VENDOR "Brian Paul"
72
73
74
75 /* Silence compiler warnings */
76 extern void Fake_glXDummyFunc( void );
77 void Fake_glXDummyFunc( void )
78 {
79 (void) kernel8;
80 (void) DitherValues;
81 (void) HPCR_DRGB;
82 (void) kernel1;
83 }
84
85
86
87 #define DONT_CARE -1
88
89
90
91 #define MAX_VISUALS 100
92 static XMesaVisual VisualTable[MAX_VISUALS];
93 static int NumVisuals = 0;
94
95
96
97 /*
98 * This struct and some code fragments borrowed
99 * from Mark Kilgard's GLUT library.
100 */
101 typedef struct _OverlayInfo {
102 /* Avoid 64-bit portability problems by being careful to use
103 longs due to the way XGetWindowProperty is specified. Note
104 that these parameters are passed as CARD32s over X
105 protocol. */
106 unsigned long overlay_visual;
107 long transparent_type;
108 long value;
109 long layer;
110 } OverlayInfo;
111
112
113
114 /* Macro to handle c_class vs class field name in XVisualInfo struct */
115 #if defined(__cplusplus) || defined(c_plusplus)
116 #define CLASS c_class
117 #else
118 #define CLASS class
119 #endif
120
121
122
123
124 /*
125 * Test if the given XVisualInfo is usable for Mesa rendering.
126 */
127 static GLboolean is_usable_visual( XVisualInfo *vinfo )
128 {
129 switch (vinfo->CLASS) {
130 case StaticGray:
131 case GrayScale:
132 /* Any StaticGray/GrayScale visual works in RGB or CI mode */
133 return GL_TRUE;
134 case StaticColor:
135 case PseudoColor:
136 /* Any StaticColor/PseudoColor visual of at least 4 bits */
137 if (vinfo->depth>=4) {
138 return GL_TRUE;
139 }
140 else {
141 return GL_FALSE;
142 }
143 case TrueColor:
144 case DirectColor:
145 /* Any depth of TrueColor or DirectColor works in RGB mode */
146 return GL_TRUE;
147 default:
148 /* This should never happen */
149 return GL_FALSE;
150 }
151 }
152
153
154
155 /*
156 * Return the level (overlay, normal, underlay) of a given XVisualInfo.
157 * Input: dpy - the X display
158 * vinfo - the XVisualInfo to test
159 * Return: level of the visual:
160 * 0 = normal planes
161 * >0 = overlay planes
162 * <0 = underlay planes
163 */
164 static int level_of_visual( Display *dpy, XVisualInfo *vinfo )
165 {
166 Atom overlayVisualsAtom;
167 OverlayInfo *overlay_info = NULL;
168 int numOverlaysPerScreen;
169 Status status;
170 Atom actualType;
171 int actualFormat;
172 unsigned long sizeData, bytesLeft;
173 int i;
174
175 /*
176 * The SERVER_OVERLAY_VISUALS property on the root window contains
177 * a list of overlay visuals. Get that list now.
178 */
179 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
180 if (overlayVisualsAtom == None) {
181 return 0;
182 }
183
184 status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
185 overlayVisualsAtom, 0L, (long) 10000, False,
186 overlayVisualsAtom, &actualType, &actualFormat,
187 &sizeData, &bytesLeft,
188 (unsigned char **) &overlay_info );
189
190 if (status != Success || actualType != overlayVisualsAtom ||
191 actualFormat != 32 || sizeData < 4) {
192 /* something went wrong */
193 XFree((void *) overlay_info);
194 return 0;
195 }
196
197 /* search the overlay visual list for the visual ID of interest */
198 numOverlaysPerScreen = (int) (sizeData / 4);
199 for (i=0;i<numOverlaysPerScreen;i++) {
200 OverlayInfo *ov;
201 ov = overlay_info + i;
202 if (ov->overlay_visual==vinfo->visualid) {
203 /* found the visual */
204 if (/*ov->transparent_type==1 &&*/ ov->layer!=0) {
205 int level = ov->layer;
206 XFree((void *) overlay_info);
207 return level;
208 }
209 else {
210 XFree((void *) overlay_info);
211 return 0;
212 }
213 }
214 }
215
216 /* The visual ID was not found in the overlay list. */
217 XFree((void *) overlay_info);
218 return 0;
219 }
220
221
222
223
224 /*
225 * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
226 * configuration in our list of GLX visuals.
227 */
228 static XMesaVisual
229 save_glx_visual( Display *dpy, XVisualInfo *vinfo,
230 GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
231 GLboolean stereoFlag,
232 GLint depth_size, GLint stencil_size,
233 GLint accumRedSize, GLint accumGreenSize,
234 GLint accumBlueSize, GLint accumAlphaSize,
235 GLint level )
236 {
237 GLboolean ximageFlag = GL_TRUE;
238 XMesaVisual xmvis;
239 GLint i;
240 GLboolean comparePointers;
241
242 if (dbFlag) {
243 /* Check if the MESA_BACK_BUFFER env var is set */
244 char *backbuffer = getenv("MESA_BACK_BUFFER");
245 if (backbuffer) {
246 if (backbuffer[0]=='p' || backbuffer[0]=='P') {
247 ximageFlag = GL_FALSE;
248 }
249 else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
250 ximageFlag = GL_TRUE;
251 }
252 else {
253 fprintf(stderr, "Mesa: invalid value for MESA_BACK_BUFFER ");
254 fprintf(stderr, "environment variable, using an XImage.\n");
255 }
256 }
257 }
258
259 /* Comparing IDs uses less memory but sometimes fails. */
260 /* XXX revisit this after 3.0 is finished. */
261 if (getenv("MESA_GLX_VISUAL_HACK"))
262 comparePointers = GL_TRUE;
263 else
264 comparePointers = GL_FALSE;
265
266 /* First check if a matching visual is already in the list */
267 for (i=0; i<NumVisuals; i++) {
268 XMesaVisual v = VisualTable[i];
269 if (v->display == dpy
270 && v->level == level
271 && v->ximage_flag == ximageFlag
272 && v->gl_visual->rgbMode == rgbFlag
273 && v->gl_visual->doubleBufferMode == dbFlag
274 && v->gl_visual->stereoMode == stereoFlag
275 && (v->gl_visual->alphaBits > 0) == alphaFlag
276 && (v->gl_visual->depthBits >= depth_size || depth_size == 0)
277 && (v->gl_visual->stencilBits >= stencil_size || stencil_size == 0)
278 && (v->gl_visual->accumRedBits >= accumRedSize || accumRedSize == 0)
279 && (v->gl_visual->accumGreenBits >= accumGreenSize || accumGreenSize == 0)
280 && (v->gl_visual->accumBlueBits >= accumBlueSize || accumBlueSize == 0)
281 && (v->gl_visual->accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) {
282 /* now either compare XVisualInfo pointers or visual IDs */
283 if ((!comparePointers && v->visinfo->visualid == vinfo->visualid)
284 || (comparePointers && v->vishandle == vinfo)) {
285 return v;
286 }
287 }
288 }
289
290 /* Create a new visual and add it to the list. */
291
292 if (NumVisuals>=MAX_VISUALS) {
293 fprintf( stderr, "GLX Error: maximum number of visuals exceeded\n");
294 return NULL;
295 }
296
297 xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
298 stereoFlag, ximageFlag,
299 depth_size, stencil_size,
300 accumRedSize, accumBlueSize,
301 accumBlueSize, accumAlphaSize, 0, level,
302 GLX_NONE_EXT );
303 if (xmvis) {
304 VisualTable[NumVisuals] = xmvis;
305 NumVisuals++;
306 }
307 return xmvis;
308 }
309
310
311
312 /*
313 * Create a GLX visual from a regular XVisualInfo.
314 * This is called when Fake GLX is given an XVisualInfo which wasn't
315 * returned by glXChooseVisual. Since this is the first time we're
316 * considering this visual we'll take a guess at reasonable values
317 * for depth buffer size, stencil size, accum size, etc.
318 * This is the best we can do with a client-side emulation of GLX.
319 */
320 static XMesaVisual
321 create_glx_visual( Display *dpy, XVisualInfo *visinfo )
322 {
323 int vislevel;
324
325 vislevel = level_of_visual( dpy, visinfo );
326 if (vislevel) {
327 /* Configure this visual as a CI, single-buffered overlay */
328 return save_glx_visual( dpy, visinfo,
329 GL_FALSE, /* rgb */
330 GL_FALSE, /* alpha */
331 GL_FALSE, /* double */
332 GL_FALSE, /* stereo */
333 0, /* depth bits */
334 0, /* stencil bits */
335 0,0,0,0, /* accum bits */
336 vislevel /* level */
337 );
338 }
339 else if (is_usable_visual( visinfo )) {
340 /* Configure this visual as RGB, double-buffered, depth-buffered. */
341 /* This is surely wrong for some people's needs but what else */
342 /* can be done? They should use glXChooseVisual(). */
343 return save_glx_visual( dpy, visinfo,
344 GL_TRUE, /* rgb */
345 GL_FALSE, /* alpha */
346 GL_TRUE, /* double */
347 GL_FALSE, /* stereo */
348 DEFAULT_SOFTWARE_DEPTH_BITS,
349 8 * sizeof(GLstencil),
350 8 * sizeof(GLaccum), /* r */
351 8 * sizeof(GLaccum), /* g */
352 8 * sizeof(GLaccum), /* b */
353 8 * sizeof(GLaccum), /* a */
354 0 /* level */
355 );
356 }
357 else {
358 fprintf(stderr,"Mesa: error in glXCreateContext: bad visual\n");
359 return NULL;
360 }
361 }
362
363
364
365 /*
366 * Find the GLX visual associated with an XVisualInfo.
367 */
368 static XMesaVisual
369 find_glx_visual( Display *dpy, XVisualInfo *vinfo )
370 {
371 int i;
372
373 /* First try to match pointers */
374 for (i=0;i<NumVisuals;i++) {
375 if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
376 return VisualTable[i];
377 }
378 }
379 /* try to match visual id */
380 for (i=0;i<NumVisuals;i++) {
381 if (VisualTable[i]->display==dpy
382 && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
383 return VisualTable[i];
384 }
385 }
386 return NULL;
387 }
388
389
390
391 /*
392 * Return the transparent pixel value for a GLX visual.
393 * Input: glxvis - the glx_visual
394 * Return: a pixel value or -1 if no transparent pixel
395 */
396 static int transparent_pixel( XMesaVisual glxvis )
397 {
398 Display *dpy = glxvis->display;
399 XVisualInfo *vinfo = glxvis->visinfo;
400 Atom overlayVisualsAtom;
401 OverlayInfo *overlay_info = NULL;
402 int numOverlaysPerScreen;
403 Status status;
404 Atom actualType;
405 int actualFormat;
406 unsigned long sizeData, bytesLeft;
407 int i;
408
409 /*
410 * The SERVER_OVERLAY_VISUALS property on the root window contains
411 * a list of overlay visuals. Get that list now.
412 */
413 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
414 if (overlayVisualsAtom == None) {
415 return -1;
416 }
417
418 status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
419 overlayVisualsAtom, 0L, (long) 10000, False,
420 overlayVisualsAtom, &actualType, &actualFormat,
421 &sizeData, &bytesLeft,
422 (unsigned char **) &overlay_info );
423
424 if (status != Success || actualType != overlayVisualsAtom ||
425 actualFormat != 32 || sizeData < 4) {
426 /* something went wrong */
427 XFree((void *) overlay_info);
428 return -1;
429 }
430
431 /* search the overlay visual list for the visual ID of interest */
432 numOverlaysPerScreen = (int) (sizeData / 4);
433 for (i=0;i<numOverlaysPerScreen;i++) {
434 OverlayInfo *ov;
435 ov = overlay_info + i;
436 if (ov->overlay_visual==vinfo->visualid) {
437 /* found it! */
438 if (ov->transparent_type==0) {
439 /* type 0 indicates no transparency */
440 XFree((void *) overlay_info);
441 return -1;
442 }
443 else {
444 /* ov->value is the transparent pixel */
445 XFree((void *) overlay_info);
446 return ov->value;
447 }
448 }
449 }
450
451 /* The visual ID was not found in the overlay list. */
452 XFree((void *) overlay_info);
453 return -1;
454 }
455
456
457
458 /*
459 * Try to get an X visual which matches the given arguments.
460 */
461 static XVisualInfo *get_visual( Display *dpy, int scr,
462 unsigned int depth, int xclass )
463 {
464 XVisualInfo temp, *vis;
465 long mask;
466 int n;
467 unsigned int default_depth;
468 int default_class;
469
470 mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
471 temp.screen = scr;
472 temp.depth = depth;
473 temp.CLASS = xclass;
474
475 default_depth = DefaultDepth(dpy,scr);
476 default_class = DefaultVisual(dpy,scr)->CLASS;
477
478 if (depth==default_depth && xclass==default_class) {
479 /* try to get root window's visual */
480 temp.visualid = DefaultVisual(dpy,scr)->visualid;
481 mask |= VisualIDMask;
482 }
483
484 vis = XGetVisualInfo( dpy, mask, &temp, &n );
485
486 /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
487 * An SGI Infinite Reality system, for example, can have 30bpp pixels:
488 * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel.
489 */
490 if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
491 if (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 &&
492 _mesa_bitcount((GLuint) vis->green_mask) <= 8 &&
493 _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) {
494 return vis;
495 }
496 else {
497 XFree((void *) vis);
498 return NULL;
499 }
500 }
501
502 return vis;
503 }
504
505
506
507 /*
508 * Retrieve the value of the given environment variable and find
509 * the X visual which matches it.
510 * Input: dpy - the display
511 * screen - the screen number
512 * varname - the name of the environment variable
513 * Return: an XVisualInfo pointer to NULL if error.
514 */
515 static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname)
516 {
517 char value[100], type[100];
518 int depth, xclass = -1;
519 XVisualInfo *vis;
520
521 if (!getenv( varname )) {
522 return NULL;
523 }
524
525 strncpy( value, getenv(varname), 100 );
526 value[99] = 0;
527
528 sscanf( value, "%s %d", type, &depth );
529
530 if (strcmp(type,"TrueColor")==0) xclass = TrueColor;
531 else if (strcmp(type,"DirectColor")==0) xclass = DirectColor;
532 else if (strcmp(type,"PseudoColor")==0) xclass = PseudoColor;
533 else if (strcmp(type,"StaticColor")==0) xclass = StaticColor;
534 else if (strcmp(type,"GrayScale")==0) xclass = GrayScale;
535 else if (strcmp(type,"StaticGray")==0) xclass = StaticGray;
536
537 if (xclass>-1 && depth>0) {
538 vis = get_visual( dpy, scr, depth, xclass );
539 if (vis) {
540 return vis;
541 }
542 }
543
544 fprintf( stderr, "Mesa: GLX unable to find visual class=%s, depth=%d.\n",
545 type, depth );
546 return NULL;
547 }
548
549
550
551 /*
552 * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
553 * Input: dpy, screen - X display and screen number
554 * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
555 * min_depth - minimum visual depth
556 * preferred_class - preferred GLX visual class or DONT_CARE
557 * Return: pointer to an XVisualInfo or NULL.
558 */
559 static XVisualInfo *choose_x_visual( Display *dpy, int screen,
560 GLboolean rgba, int min_depth,
561 int preferred_class )
562 {
563 XVisualInfo *vis;
564 int xclass, visclass = 0;
565 int depth;
566
567 if (rgba) {
568 Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
569 /* First see if the MESA_RGB_VISUAL env var is defined */
570 vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
571 if (vis) {
572 return vis;
573 }
574 /* Otherwise, search for a suitable visual */
575 if (preferred_class==DONT_CARE) {
576 for (xclass=0;xclass<6;xclass++) {
577 switch (xclass) {
578 case 0: visclass = TrueColor; break;
579 case 1: visclass = DirectColor; break;
580 case 2: visclass = PseudoColor; break;
581 case 3: visclass = StaticColor; break;
582 case 4: visclass = GrayScale; break;
583 case 5: visclass = StaticGray; break;
584 }
585 if (min_depth==0) {
586 /* start with shallowest */
587 for (depth=0;depth<=32;depth++) {
588 if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
589 /* Special case: try to get 8-bit PseudoColor before */
590 /* 8-bit TrueColor */
591 vis = get_visual( dpy, screen, 8, PseudoColor );
592 if (vis) {
593 return vis;
594 }
595 }
596 vis = get_visual( dpy, screen, depth, visclass );
597 if (vis) {
598 return vis;
599 }
600 }
601 }
602 else {
603 /* start with deepest */
604 for (depth=32;depth>=min_depth;depth--) {
605 if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
606 /* Special case: try to get 8-bit PseudoColor before */
607 /* 8-bit TrueColor */
608 vis = get_visual( dpy, screen, 8, PseudoColor );
609 if (vis) {
610 return vis;
611 }
612 }
613 vis = get_visual( dpy, screen, depth, visclass );
614 if (vis) {
615 return vis;
616 }
617 }
618 }
619 }
620 }
621 else {
622 /* search for a specific visual class */
623 switch (preferred_class) {
624 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
625 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
626 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
627 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
628 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
629 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
630 default: return NULL;
631 }
632 if (min_depth==0) {
633 /* start with shallowest */
634 for (depth=0;depth<=32;depth++) {
635 vis = get_visual( dpy, screen, depth, visclass );
636 if (vis) {
637 return vis;
638 }
639 }
640 }
641 else {
642 /* start with deepest */
643 for (depth=32;depth>=min_depth;depth--) {
644 vis = get_visual( dpy, screen, depth, visclass );
645 if (vis) {
646 return vis;
647 }
648 }
649 }
650 }
651 }
652 else {
653 /* First see if the MESA_CI_VISUAL env var is defined */
654 vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
655 if (vis) {
656 return vis;
657 }
658 /* Otherwise, search for a suitable visual, starting with shallowest */
659 if (preferred_class==DONT_CARE) {
660 for (xclass=0;xclass<4;xclass++) {
661 switch (xclass) {
662 case 0: visclass = PseudoColor; break;
663 case 1: visclass = StaticColor; break;
664 case 2: visclass = GrayScale; break;
665 case 3: visclass = StaticGray; break;
666 }
667 /* try 8-bit up through 16-bit */
668 for (depth=8;depth<=16;depth++) {
669 vis = get_visual( dpy, screen, depth, visclass );
670 if (vis) {
671 return vis;
672 }
673 }
674 /* try min_depth up to 8-bit */
675 for (depth=min_depth;depth<8;depth++) {
676 vis = get_visual( dpy, screen, depth, visclass );
677 if (vis) {
678 return vis;
679 }
680 }
681 }
682 }
683 else {
684 /* search for a specific visual class */
685 switch (preferred_class) {
686 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
687 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
688 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
689 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
690 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
691 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
692 default: return NULL;
693 }
694 /* try 8-bit up through 16-bit */
695 for (depth=8;depth<=16;depth++) {
696 vis = get_visual( dpy, screen, depth, visclass );
697 if (vis) {
698 return vis;
699 }
700 }
701 /* try min_depth up to 8-bit */
702 for (depth=min_depth;depth<8;depth++) {
703 vis = get_visual( dpy, screen, depth, visclass );
704 if (vis) {
705 return vis;
706 }
707 }
708 }
709 }
710
711 /* didn't find a visual */
712 return NULL;
713 }
714
715
716
717 /*
718 * Find the deepest X over/underlay visual of at least min_depth.
719 * Input: dpy, screen - X display and screen number
720 * level - the over/underlay level
721 * trans_type - transparent pixel type: GLX_NONE_EXT,
722 * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
723 * or DONT_CARE
724 * trans_value - transparent pixel value or DONT_CARE
725 * min_depth - minimum visual depth
726 * preferred_class - preferred GLX visual class or DONT_CARE
727 * Return: pointer to an XVisualInfo or NULL.
728 */
729 static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr,
730 GLboolean rgbFlag,
731 int level, int trans_type,
732 int trans_value,
733 int min_depth,
734 int preferred_class )
735 {
736 Atom overlayVisualsAtom;
737 OverlayInfo *overlay_info;
738 int numOverlaysPerScreen;
739 Status status;
740 Atom actualType;
741 int actualFormat;
742 unsigned long sizeData, bytesLeft;
743 int i;
744 XVisualInfo *deepvis;
745 int deepest;
746
747 /*DEBUG int tt, tv; */
748
749 switch (preferred_class) {
750 case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break;
751 case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break;
752 case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break;
753 case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break;
754 case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break;
755 case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break;
756 default: preferred_class = DONT_CARE;
757 }
758
759 /*
760 * The SERVER_OVERLAY_VISUALS property on the root window contains
761 * a list of overlay visuals. Get that list now.
762 */
763 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
764 if (overlayVisualsAtom == (Atom) None) {
765 return NULL;
766 }
767
768 status = XGetWindowProperty(dpy, RootWindow( dpy, scr ),
769 overlayVisualsAtom, 0L, (long) 10000, False,
770 overlayVisualsAtom, &actualType, &actualFormat,
771 &sizeData, &bytesLeft,
772 (unsigned char **) &overlay_info );
773
774 if (status != Success || actualType != overlayVisualsAtom ||
775 actualFormat != 32 || sizeData < 4) {
776 /* something went wrong */
777 return NULL;
778 }
779
780 /* Search for the deepest overlay which satisifies all criteria. */
781 deepest = min_depth;
782 deepvis = NULL;
783
784 numOverlaysPerScreen = (int) (sizeData / 4);
785 for (i=0;i<numOverlaysPerScreen;i++) {
786 XVisualInfo *vislist, vistemplate;
787 int count;
788 OverlayInfo *ov;
789 ov = overlay_info + i;
790
791 if (ov->layer!=level) {
792 /* failed overlay level criteria */
793 continue;
794 }
795 if (!(trans_type==DONT_CARE
796 || (trans_type==GLX_TRANSPARENT_INDEX_EXT
797 && ov->transparent_type>0)
798 || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
799 /* failed transparent pixel type criteria */
800 continue;
801 }
802 if (trans_value!=DONT_CARE && trans_value!=ov->value) {
803 /* failed transparent pixel value criteria */
804 continue;
805 }
806
807 /* get XVisualInfo and check the depth */
808 vistemplate.visualid = ov->overlay_visual;
809 vistemplate.screen = scr;
810 vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
811 &vistemplate, &count );
812
813 if (count!=1) {
814 /* something went wrong */
815 continue;
816 }
817 if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
818 /* wrong visual class */
819 continue;
820 }
821
822 /* if RGB was requested, make sure we have True/DirectColor */
823 if (rgbFlag && vislist->CLASS != TrueColor
824 && vislist->CLASS != DirectColor)
825 continue;
826
827 /* if CI was requested, make sure we have a color indexed visual */
828 if (!rgbFlag
829 && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor))
830 continue;
831
832 if (deepvis==NULL || vislist->depth > deepest) {
833 /* YES! found a satisfactory visual */
834 if (deepvis) {
835 XFree( deepvis );
836 }
837 deepest = vislist->depth;
838 deepvis = vislist;
839 /* DEBUG tt = ov->transparent_type;*/
840 /* DEBUG tv = ov->value; */
841 }
842 }
843
844 /*DEBUG
845 if (deepvis) {
846 printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n",
847 deepvis->visualid, level, deepvis->depth, tt, tv );
848 }
849 */
850 return deepvis;
851 }
852
853
854
855 static XVisualInfo *
856 Fake_glXChooseVisual( Display *dpy, int screen, int *list )
857 {
858 int *parselist;
859 XVisualInfo *vis;
860 int min_ci = 0;
861 int min_red=0, min_green=0, min_blue=0;
862 GLboolean rgb_flag = GL_FALSE;
863 GLboolean alpha_flag = GL_FALSE;
864 GLboolean double_flag = GL_FALSE;
865 GLboolean stereo_flag = GL_FALSE;
866 GLint depth_size = 0;
867 GLint stencil_size = 0;
868 GLint accumRedSize = 0;
869 GLint accumGreenSize = 0;
870 GLint accumBlueSize = 0;
871 GLint accumAlphaSize = 0;
872 int level = 0;
873 int visual_type = DONT_CARE;
874 int trans_type = DONT_CARE;
875 int trans_value = DONT_CARE;
876 GLint caveat = DONT_CARE;
877
878 parselist = list;
879
880 while (*parselist) {
881
882 switch (*parselist) {
883 case GLX_USE_GL:
884 /* ignore */
885 parselist++;
886 break;
887 case GLX_BUFFER_SIZE:
888 parselist++;
889 min_ci = *parselist++;
890 break;
891 case GLX_LEVEL:
892 parselist++;
893 level = *parselist++;
894 break;
895 case GLX_RGBA:
896 rgb_flag = GL_TRUE;
897 parselist++;
898 break;
899 case GLX_DOUBLEBUFFER:
900 double_flag = GL_TRUE;
901 parselist++;
902 break;
903 case GLX_STEREO:
904 stereo_flag = GL_TRUE;
905 return NULL;
906 case GLX_AUX_BUFFERS:
907 /* ignore */
908 parselist++;
909 parselist++;
910 break;
911 case GLX_RED_SIZE:
912 parselist++;
913 min_red = *parselist++;
914 break;
915 case GLX_GREEN_SIZE:
916 parselist++;
917 min_green = *parselist++;
918 break;
919 case GLX_BLUE_SIZE:
920 parselist++;
921 min_blue = *parselist++;
922 break;
923 case GLX_ALPHA_SIZE:
924 parselist++;
925 {
926 GLint size = *parselist++;
927 alpha_flag = size>0 ? 1 : 0;
928 }
929 break;
930 case GLX_DEPTH_SIZE:
931 parselist++;
932 depth_size = *parselist++;
933 break;
934 case GLX_STENCIL_SIZE:
935 parselist++;
936 stencil_size = *parselist++;
937 break;
938 case GLX_ACCUM_RED_SIZE:
939 parselist++;
940 {
941 GLint size = *parselist++;
942 accumRedSize = MAX2( accumRedSize, size );
943 }
944 break;
945 case GLX_ACCUM_GREEN_SIZE:
946 parselist++;
947 {
948 GLint size = *parselist++;
949 accumGreenSize = MAX2( accumGreenSize, size );
950 }
951 break;
952 case GLX_ACCUM_BLUE_SIZE:
953 parselist++;
954 {
955 GLint size = *parselist++;
956 accumBlueSize = MAX2( accumBlueSize, size );
957 }
958 break;
959 case GLX_ACCUM_ALPHA_SIZE:
960 parselist++;
961 {
962 GLint size = *parselist++;
963 accumAlphaSize = MAX2( accumAlphaSize, size );
964 }
965 break;
966
967 /*
968 * GLX_EXT_visual_info extension
969 */
970 case GLX_X_VISUAL_TYPE_EXT:
971 parselist++;
972 visual_type = *parselist++;
973 break;
974 case GLX_TRANSPARENT_TYPE_EXT:
975 parselist++;
976 trans_type = *parselist++;
977 break;
978 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
979 parselist++;
980 trans_value = *parselist++;
981 break;
982 case GLX_TRANSPARENT_RED_VALUE_EXT:
983 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
984 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
985 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
986 /* ignore */
987 parselist++;
988 parselist++;
989 break;
990
991 /*
992 * GLX_EXT_visual_info extension
993 */
994 case GLX_VISUAL_CAVEAT_EXT:
995 parselist++;
996 caveat = *parselist++; /* ignored for now */
997 break;
998
999 case None:
1000 break;
1001 default:
1002 /* undefined attribute */
1003 return NULL;
1004 }
1005 }
1006
1007 /*
1008 * Since we're only simulating the GLX extension this function will never
1009 * find any real GL visuals. Instead, all we can do is try to find an RGB
1010 * or CI visual of appropriate depth. Other requested attributes such as
1011 * double buffering, depth buffer, etc. will be associated with the X
1012 * visual and stored in the VisualTable[].
1013 */
1014 if (level==0) {
1015 /* normal color planes */
1016 if (rgb_flag) {
1017 /* Get an RGB visual */
1018 int min_rgb = min_red + min_green + min_blue;
1019 if (min_rgb>1 && min_rgb<8) {
1020 /* a special case to be sure we can get a monochrome visual */
1021 min_rgb = 1;
1022 }
1023 vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
1024 }
1025 else {
1026 /* Get a color index visual */
1027 vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
1028 accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0;
1029 }
1030 }
1031 else {
1032 /* over/underlay planes */
1033 if (rgb_flag) {
1034 /* rgba overlay */
1035 int min_rgb = min_red + min_green + min_blue;
1036 if (min_rgb>1 && min_rgb<8) {
1037 /* a special case to be sure we can get a monochrome visual */
1038 min_rgb = 1;
1039 }
1040 vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
1041 trans_type, trans_value, min_rgb, visual_type );
1042 }
1043 else {
1044 /* color index overlay */
1045 vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
1046 trans_type, trans_value, min_ci, visual_type );
1047 }
1048 }
1049
1050 if (vis) {
1051 /* Note: we're not exactly obeying the glXChooseVisual rules here.
1052 * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
1053 * largest depth buffer size, which is 32bits/value. Instead, we
1054 * return 16 to maintain performance with earlier versions of Mesa.
1055 */
1056 if (depth_size > 24)
1057 depth_size = 31; /* 32 causes int overflow problems */
1058 else if (depth_size > 16)
1059 depth_size = 24;
1060 else if (depth_size > 0)
1061 depth_size = DEFAULT_SOFTWARE_DEPTH_BITS; /*16*/
1062
1063 /* we only support one size of stencil and accum buffers. */
1064 if (stencil_size > 0)
1065 stencil_size = STENCIL_BITS;
1066 if (accumRedSize > 0)
1067 accumRedSize = ACCUM_BITS;
1068 if (accumGreenSize > 0)
1069 accumGreenSize = ACCUM_BITS;
1070 if (accumBlueSize > 0)
1071 accumBlueSize = ACCUM_BITS;
1072 if (accumAlphaSize > 0)
1073 accumAlphaSize = ACCUM_BITS;
1074 if (!save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
1075 stereo_flag, depth_size, stencil_size,
1076 accumRedSize, accumGreenSize,
1077 accumBlueSize, accumAlphaSize,
1078 level ))
1079 return NULL;
1080 }
1081
1082 return vis;
1083 }
1084
1085
1086
1087
1088 static GLXContext
1089 Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
1090 GLXContext share_list, Bool direct )
1091 {
1092 XMesaVisual glxvis;
1093 XMesaContext xmctx;
1094
1095 /* deallocate unused windows/buffers */
1096 XMesaGarbageCollect();
1097
1098 glxvis = find_glx_visual( dpy, visinfo );
1099 if (!glxvis) {
1100 /* This visual wasn't found with glXChooseVisual() */
1101 glxvis = create_glx_visual( dpy, visinfo );
1102 if (!glxvis) {
1103 /* unusable visual */
1104 return NULL;
1105 }
1106 }
1107
1108 xmctx = XMesaCreateContext( glxvis, (XMesaContext) share_list );
1109 if (xmctx) {
1110 /* set the direct/indirect flag */
1111 xmctx->direct = direct;
1112 }
1113 return (GLXContext) xmctx;
1114 }
1115
1116
1117 static GLXContext MakeCurrent_PrevContext = 0;
1118 static GLXDrawable MakeCurrent_PrevDrawable = 0;
1119 static GLXDrawable MakeCurrent_PrevReadable = 0;
1120 static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
1121 static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
1122
1123 /* GLX 1.3 and later */
1124 static Bool
1125 Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
1126 GLXDrawable read, GLXContext ctx )
1127 {
1128 if (ctx && draw && read) {
1129 XMesaBuffer drawBuffer, readBuffer;
1130 XMesaContext xmctx = (XMesaContext) ctx;
1131
1132 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
1133 if (ctx == MakeCurrent_PrevContext
1134 && draw == MakeCurrent_PrevDrawable) {
1135 drawBuffer = MakeCurrent_PrevDrawBuffer;
1136 }
1137 else {
1138 drawBuffer = XMesaFindBuffer( dpy, draw );
1139 }
1140 if (!drawBuffer) {
1141 /* drawable must be a new window! */
1142 drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, (XMesaContext) ctx );
1143 if (!drawBuffer) {
1144 /* Out of memory, or context/drawable depth mismatch */
1145 return False;
1146 }
1147 }
1148
1149 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
1150 if (ctx == MakeCurrent_PrevContext
1151 && read == MakeCurrent_PrevReadable) {
1152 readBuffer = MakeCurrent_PrevReadBuffer;
1153 }
1154 else {
1155 readBuffer = XMesaFindBuffer( dpy, read );
1156 }
1157 if (!readBuffer) {
1158 /* drawable must be a new window! */
1159 readBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, read, (XMesaContext) ctx );
1160 if (!readBuffer) {
1161 /* Out of memory, or context/drawable depth mismatch */
1162 return False;
1163 }
1164 }
1165
1166 MakeCurrent_PrevContext = ctx;
1167 MakeCurrent_PrevDrawable = draw;
1168 MakeCurrent_PrevReadable = read;
1169 MakeCurrent_PrevDrawBuffer = drawBuffer;
1170 MakeCurrent_PrevReadBuffer = readBuffer;
1171
1172 /* Now make current! */
1173 return (Bool) XMesaMakeCurrent2((XMesaContext) ctx, drawBuffer, readBuffer);
1174 }
1175 else if (!ctx && !draw && !read) {
1176 /* release current context w/out assigning new one. */
1177 XMesaMakeCurrent( NULL, NULL );
1178 MakeCurrent_PrevContext = 0;
1179 MakeCurrent_PrevDrawable = 0;
1180 MakeCurrent_PrevReadable = 0;
1181 MakeCurrent_PrevDrawBuffer = 0;
1182 MakeCurrent_PrevReadBuffer = 0;
1183 return True;
1184 }
1185 else {
1186 /* The args must either all be non-zero or all zero.
1187 * This is an error.
1188 */
1189 return False;
1190 }
1191 }
1192
1193
1194
1195 static Bool
1196 Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
1197 {
1198 return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx );
1199 }
1200
1201
1202
1203 static GLXPixmap
1204 Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
1205 {
1206 XMesaVisual v;
1207 XMesaBuffer b;
1208
1209 v = find_glx_visual( dpy, visinfo );
1210 if (!v) {
1211 v = create_glx_visual( dpy, visinfo );
1212 if (!v) {
1213 /* unusable visual */
1214 return 0;
1215 }
1216 }
1217
1218 b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
1219 if (!b) {
1220 return 0;
1221 }
1222 return b->frontbuffer;
1223 }
1224
1225
1226 #ifdef GLX_MESA_pixmap_colormap
1227 static GLXPixmap
1228 Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
1229 Pixmap pixmap, Colormap cmap )
1230 {
1231 XMesaVisual v;
1232 XMesaBuffer b;
1233
1234 v = find_glx_visual( dpy, visinfo );
1235 if (!v) {
1236 v = create_glx_visual( dpy, visinfo );
1237 if (!v) {
1238 /* unusable visual */
1239 return 0;
1240 }
1241 }
1242
1243 b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
1244 if (!b) {
1245 return 0;
1246 }
1247 return b->frontbuffer;
1248 }
1249 #endif
1250
1251
1252 static void
1253 Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
1254 {
1255 XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
1256 if (b) {
1257 XMesaDestroyBuffer(b);
1258 }
1259 else if (getenv("MESA_DEBUG")) {
1260 fprintf( stderr, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
1261 }
1262 }
1263
1264
1265
1266 static void
1267 Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
1268 unsigned long mask )
1269 {
1270 XMesaContext xm_src = (XMesaContext) src;
1271 XMesaContext xm_dst = (XMesaContext) dst;
1272 (void) dpy;
1273 _mesa_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, (GLuint) mask );
1274 }
1275
1276
1277
1278 static Bool
1279 Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
1280 {
1281 /* Mesa's GLX isn't really an X extension but we try to act like one. */
1282 (void) dpy;
1283 (void) errorb;
1284 (void) event;
1285 return True;
1286 }
1287
1288
1289 extern void _kw_ungrab_all( Display *dpy );
1290 void _kw_ungrab_all( Display *dpy )
1291 {
1292 XUngrabPointer( dpy, CurrentTime );
1293 XUngrabKeyboard( dpy, CurrentTime );
1294 }
1295
1296
1297 static void
1298 Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
1299 {
1300 (void) dpy;
1301 MakeCurrent_PrevContext = 0;
1302 MakeCurrent_PrevDrawable = 0;
1303 MakeCurrent_PrevReadable = 0;
1304 MakeCurrent_PrevDrawBuffer = 0;
1305 MakeCurrent_PrevReadBuffer = 0;
1306 XMesaDestroyContext( (XMesaContext) ctx );
1307 XMesaGarbageCollect();
1308 }
1309
1310
1311
1312 static Bool
1313 Fake_glXIsDirect( Display *dpy, GLXContext ctx )
1314 {
1315 (void) dpy;
1316 return ((XMesaContext) ctx)->direct;
1317 }
1318
1319
1320
1321 static void
1322 Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
1323 {
1324 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1325
1326 if (buffer) {
1327 XMesaSwapBuffers(buffer);
1328 }
1329 else if (getenv("MESA_DEBUG")) {
1330 fprintf(stderr, "Mesa Warning: glXSwapBuffers: invalid drawable\n");
1331 }
1332 }
1333
1334
1335
1336 #ifdef GLX_MESA_copy_sub_buffer
1337 static void
1338 Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
1339 int x, int y, int width, int height )
1340 {
1341 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1342 if (buffer) {
1343 XMesaCopySubBuffer(buffer, x, y, width, height);
1344 }
1345 else if (getenv("MESA_DEBUG")) {
1346 fprintf(stderr, "Mesa Warning: glXCopySubBufferMESA: invalid drawable\n");
1347 }
1348 }
1349 #endif
1350
1351
1352
1353 static Bool
1354 Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
1355 {
1356 (void) dpy;
1357 /* Return GLX version, not Mesa version */
1358 assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
1359 *maj = CLIENT_MAJOR_VERSION;
1360 *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
1361 return True;
1362 }
1363
1364
1365
1366 /*
1367 * Query the GLX attributes of the given XVisualInfo.
1368 */
1369 static int
1370 Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
1371 int attrib, int *value )
1372 {
1373 XMesaVisual glxvis;
1374
1375 glxvis = find_glx_visual( dpy, visinfo );
1376 if (!glxvis) {
1377 /* this visual wasn't obtained with glXChooseVisual */
1378 glxvis = create_glx_visual( dpy, visinfo );
1379 if (!glxvis) {
1380 /* this visual can't be used for GL rendering */
1381 if (attrib==GLX_USE_GL) {
1382 *value = (int) False;
1383 return 0;
1384 }
1385 else {
1386 /*fprintf( stderr, "Mesa: Error in glXGetConfig: bad visual\n");*/
1387 return GLX_BAD_VISUAL;
1388 }
1389 }
1390 }
1391
1392 switch(attrib) {
1393 case GLX_USE_GL:
1394 *value = (int) True;
1395 return 0;
1396 case GLX_BUFFER_SIZE:
1397 *value = visinfo->depth;
1398 return 0;
1399 case GLX_LEVEL:
1400 *value = glxvis->level;
1401 return 0;
1402 case GLX_RGBA:
1403 if (glxvis->gl_visual->rgbMode) {
1404 *value = True;
1405 }
1406 else {
1407 *value = False;
1408 }
1409 return 0;
1410 case GLX_DOUBLEBUFFER:
1411 *value = (int) glxvis->gl_visual->doubleBufferMode;
1412 return 0;
1413 case GLX_STEREO:
1414 *value = (int) glxvis->gl_visual->stereoMode;
1415 return 0;
1416 case GLX_AUX_BUFFERS:
1417 *value = (int) False;
1418 return 0;
1419 case GLX_RED_SIZE:
1420 *value = glxvis->gl_visual->redBits;
1421 return 0;
1422 case GLX_GREEN_SIZE:
1423 *value = glxvis->gl_visual->greenBits;
1424 return 0;
1425 case GLX_BLUE_SIZE:
1426 *value = glxvis->gl_visual->blueBits;
1427 return 0;
1428 case GLX_ALPHA_SIZE:
1429 *value = glxvis->gl_visual->alphaBits;
1430 return 0;
1431 case GLX_DEPTH_SIZE:
1432 *value = glxvis->gl_visual->depthBits;
1433 return 0;
1434 case GLX_STENCIL_SIZE:
1435 *value = glxvis->gl_visual->stencilBits;
1436 return 0;
1437 case GLX_ACCUM_RED_SIZE:
1438 *value = glxvis->gl_visual->accumRedBits;
1439 return 0;
1440 case GLX_ACCUM_GREEN_SIZE:
1441 *value = glxvis->gl_visual->accumGreenBits;
1442 return 0;
1443 case GLX_ACCUM_BLUE_SIZE:
1444 *value = glxvis->gl_visual->accumBlueBits;
1445 return 0;
1446 case GLX_ACCUM_ALPHA_SIZE:
1447 *value = glxvis->gl_visual->accumAlphaBits;
1448 return 0;
1449
1450 /*
1451 * GLX_EXT_visual_info extension
1452 */
1453 case GLX_X_VISUAL_TYPE_EXT:
1454 switch (glxvis->visinfo->CLASS) {
1455 case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0;
1456 case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0;
1457 case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0;
1458 case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0;
1459 case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0;
1460 case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0;
1461 }
1462 return 0;
1463 case GLX_TRANSPARENT_TYPE_EXT:
1464 if (glxvis->level==0) {
1465 /* normal planes */
1466 *value = GLX_NONE_EXT;
1467 }
1468 else if (glxvis->level>0) {
1469 /* overlay */
1470 if (glxvis->gl_visual->rgbMode) {
1471 *value = GLX_TRANSPARENT_RGB_EXT;
1472 }
1473 else {
1474 *value = GLX_TRANSPARENT_INDEX_EXT;
1475 }
1476 }
1477 else if (glxvis->level<0) {
1478 /* underlay */
1479 *value = GLX_NONE_EXT;
1480 }
1481 return 0;
1482 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
1483 {
1484 int pixel = transparent_pixel( glxvis );
1485 if (pixel>=0) {
1486 *value = pixel;
1487 }
1488 /* else undefined */
1489 }
1490 return 0;
1491 case GLX_TRANSPARENT_RED_VALUE_EXT:
1492 /* undefined */
1493 return 0;
1494 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
1495 /* undefined */
1496 return 0;
1497 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
1498 /* undefined */
1499 return 0;
1500 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
1501 /* undefined */
1502 return 0;
1503
1504 /*
1505 * GLX_EXT_visual_info extension
1506 */
1507 case GLX_VISUAL_CAVEAT_EXT:
1508 /* test for zero, just in case */
1509 if (glxvis->VisualCaveat > 0)
1510 *value = glxvis->VisualCaveat;
1511 else
1512 *value = GLX_NONE_EXT;
1513 return 0;
1514
1515 /*
1516 * Extensions
1517 */
1518 default:
1519 return GLX_BAD_ATTRIBUTE;
1520 }
1521 }
1522
1523
1524
1525 static void
1526 Fake_glXWaitGL( void )
1527 {
1528 XMesaContext xmesa = XMesaGetCurrentContext();
1529 XMesaFlush( xmesa );
1530 }
1531
1532
1533
1534 static void
1535 Fake_glXWaitX( void )
1536 {
1537 XMesaContext xmesa = XMesaGetCurrentContext();
1538 XMesaFlush( xmesa );
1539 }
1540
1541
1542 /*
1543 * Return the extensions string, which is 3Dfx-dependant.
1544 */
1545 static const char *get_extensions( void )
1546 {
1547 #ifdef FX
1548 const char *fx = getenv("MESA_GLX_FX");
1549 if (fx && fx[0] != 'd') {
1550 return "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_EXT_visual_rating GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync GLX_MESA_set_3dfx_mode GLX_ARB_get_proc_address";
1551 }
1552 #endif
1553 return "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_EXT_visual_rating GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync GLX_ARB_get_proc_address";
1554 }
1555
1556
1557
1558 /* GLX 1.1 and later */
1559 static const char *
1560 Fake_glXQueryExtensionsString( Display *dpy, int screen )
1561 {
1562 (void) dpy;
1563 (void) screen;
1564 return get_extensions();
1565 }
1566
1567
1568
1569 /* GLX 1.1 and later */
1570 static const char *
1571 Fake_glXQueryServerString( Display *dpy, int screen, int name )
1572 {
1573 static char version[1000];
1574 sprintf(version, "%d.%d %s", SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION,
1575 MESA_GLX_VERSION);
1576
1577 (void) dpy;
1578 (void) screen;
1579
1580 switch (name) {
1581 case GLX_EXTENSIONS:
1582 return get_extensions();
1583 case GLX_VENDOR:
1584 return VENDOR;
1585 case GLX_VERSION:
1586 return version;
1587 default:
1588 return NULL;
1589 }
1590 }
1591
1592
1593
1594 /* GLX 1.1 and later */
1595 static const char *
1596 Fake_glXGetClientString( Display *dpy, int name )
1597 {
1598 static char version[1000];
1599 sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, CLIENT_MINOR_VERSION,
1600 MESA_GLX_VERSION);
1601
1602 (void) dpy;
1603
1604 switch (name) {
1605 case GLX_EXTENSIONS:
1606 return get_extensions();
1607 case GLX_VENDOR:
1608 return VENDOR;
1609 case GLX_VERSION:
1610 return version;
1611 default:
1612 return NULL;
1613 }
1614 }
1615
1616
1617
1618 /*
1619 * GLX 1.3 and later
1620 */
1621
1622 static GLXFBConfig *
1623 Fake_glXChooseFBConfig( Display *dpy, int screen,
1624 const int *attribList, int *nitems )
1625 {
1626 (void) dpy;
1627 (void) screen;
1628 (void) attribList;
1629 (void) nitems;
1630 return 0;
1631 }
1632
1633
1634 static int
1635 Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
1636 int attribute, int *value )
1637 {
1638 (void) dpy;
1639 (void) config;
1640 (void) attribute;
1641 (void) value;
1642 return 0;
1643 }
1644
1645
1646 static GLXFBConfig *
1647 Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
1648 {
1649 (void) dpy;
1650 (void) screen;
1651 (void) nelements;
1652 return 0;
1653 }
1654
1655
1656 static XVisualInfo *
1657 Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
1658 {
1659 (void) dpy;
1660 (void) config;
1661 return 0;
1662 }
1663
1664
1665 static GLXWindow
1666 Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
1667 const int *attribList )
1668 {
1669 (void) dpy;
1670 (void) config;
1671 (void) win;
1672 (void) attribList;
1673 return 0;
1674 }
1675
1676
1677 static void
1678 Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
1679 {
1680 (void) dpy;
1681 (void) window;
1682 return;
1683 }
1684
1685
1686 static GLXPixmap
1687 Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
1688 const int *attribList )
1689 {
1690 (void) dpy;
1691 (void) config;
1692 (void) pixmap;
1693 (void) attribList;
1694 return 0;
1695 }
1696
1697
1698 static void
1699 Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
1700 {
1701 (void) dpy;
1702 (void) pixmap;
1703 return;
1704 }
1705
1706
1707 static GLXPbuffer
1708 Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
1709 const int *attribList )
1710 {
1711 (void) dpy;
1712 (void) config;
1713 (void) attribList;
1714 return 0;
1715 }
1716
1717
1718 static void
1719 Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
1720 {
1721 (void) dpy;
1722 (void) pbuf;
1723 }
1724
1725
1726 static void
1727 Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
1728 unsigned int *value )
1729 {
1730 (void) dpy;
1731 (void) draw;
1732 (void) attribute;
1733 (void) value;
1734 }
1735
1736
1737 static GLXContext
1738 Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
1739 int renderType, GLXContext shareList, Bool direct )
1740 {
1741 (void) dpy;
1742 (void) config;
1743 (void) renderType;
1744 (void) shareList;
1745 (void) direct;
1746 return 0;
1747 }
1748
1749
1750 static int
1751 Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
1752 {
1753 (void) dpy;
1754 (void) ctx;
1755 (void) attribute;
1756 (void) value;
1757 return 0;
1758 }
1759
1760
1761 static void
1762 Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
1763 {
1764 (void) dpy;
1765 (void) drawable;
1766 (void) mask;
1767 }
1768
1769
1770 static void
1771 Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
1772 unsigned long *mask )
1773 {
1774 (void) dpy;
1775 (void) drawable;
1776 (void) mask;
1777 }
1778
1779
1780
1781 #ifdef GLX_SGI_swap_control
1782
1783 static int
1784 Fake_glXSwapIntervalSGI(int interval)
1785 {
1786 (void) interval;
1787 return 0;
1788 }
1789
1790 #endif
1791
1792
1793 #ifdef GLX_SGI_video_sync
1794
1795 static int
1796 Fake_glXGetVideoSyncSGI(unsigned int *count)
1797 {
1798 (void) count;
1799 return 0;
1800 }
1801
1802 static int
1803 Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
1804 {
1805 (void) divisor;
1806 (void) remainder;
1807 (void) count;
1808 return 0;
1809 }
1810
1811 #endif
1812
1813
1814 #ifdef GLX_SGI_make_current_read
1815
1816 static Bool
1817 Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
1818 {
1819 (void) dpy;
1820 (void) draw;
1821 (void) read;
1822 (void) ctx;
1823 return False;
1824 }
1825
1826 static GLXDrawable
1827 Fake_glXGetCurrentReadDrawableSGI(void)
1828 {
1829 return 0;
1830 }
1831
1832 #endif
1833
1834
1835 #if defined(_VL_H) && defined(GLX_SGIX_video_source)
1836
1837 static GLXVideoSourceSGIX
1838 Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
1839 {
1840 (void) dpy;
1841 (void) screen;
1842 (void) server;
1843 (void) path;
1844 (void) nodeClass;
1845 (void) drainNode;
1846 return 0;
1847 }
1848
1849 static void
1850 Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
1851 {
1852 (void) dpy;
1853 (void) src;
1854 }
1855
1856 #endif
1857
1858
1859 #ifdef GLX_EXT_import_context
1860
1861 static void
1862 Fake_glXFreeContextEXT(Display *dpy, GLXContext context)
1863 {
1864 (void) dpy;
1865 (void) context;
1866 }
1867
1868 static GLXContextID
1869 Fake_glXGetContextIDEXT(const GLXContext context)
1870 {
1871 (void) context;
1872 return 0;
1873 }
1874
1875 static Display *
1876 Fake_glXGetCurrentDisplayEXT(void)
1877 {
1878 return glXGetCurrentDisplay();
1879 }
1880
1881 static GLXContext
1882 Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID)
1883 {
1884 (void) dpy;
1885 (void) contextID;
1886 return 0;
1887 }
1888
1889 static int
1890 Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
1891 {
1892 (void) dpy;
1893 (void) context;
1894 (void) attribute;
1895 (void) value;
1896 return 0;
1897 }
1898
1899 #endif
1900
1901
1902 #ifdef GLX_SGIX_fbconfig
1903
1904 static int
1905 Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
1906 {
1907 (void) dpy;
1908 (void) config;
1909 (void) attribute;
1910 (void) value;
1911 return 0;
1912 }
1913
1914 static GLXFBConfigSGIX *
1915 Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
1916 {
1917 (void) dpy;
1918 (void) screen;
1919 (void) attrib_list;
1920 (void) nelements;
1921 return 0;
1922 }
1923
1924 static GLXPixmap
1925 Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
1926 {
1927 (void) dpy;
1928 (void) config;
1929 (void) pixmap;
1930 return 0;
1931 }
1932
1933 static GLXContext
1934 Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
1935 {
1936 (void) dpy;
1937 (void) config;
1938 (void) render_type;
1939 (void) share_list;
1940 (void) direct;
1941 return 0;
1942 }
1943
1944 static XVisualInfo *
1945 Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
1946 {
1947 (void) dpy;
1948 (void) config;
1949 return NULL;
1950 }
1951
1952 static GLXFBConfigSGIX
1953 Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
1954 {
1955 (void) dpy;
1956 (void) vis;
1957 return 0;
1958 }
1959
1960 #endif
1961
1962
1963 #ifdef GLX_SGIX_pbuffer
1964
1965 static GLXPbufferSGIX
1966 Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
1967 {
1968 (void) dpy;
1969 (void) config;
1970 (void) width;
1971 (void) height;
1972 (void) attrib_list;
1973 return 0;
1974 }
1975
1976 static void
1977 Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
1978 {
1979 (void) dpy;
1980 (void) pbuf;
1981 }
1982
1983 static int
1984 Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
1985 {
1986 (void) dpy;
1987 (void) pbuf;
1988 (void) attribute;
1989 (void) value;
1990 return 0;
1991 }
1992
1993 static void
1994 Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
1995 {
1996 (void) dpy;
1997 (void) drawable;
1998 (void) mask;
1999 }
2000
2001 static void
2002 Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
2003 {
2004 (void) dpy;
2005 (void) drawable;
2006 (void) mask;
2007 }
2008
2009 #endif
2010
2011
2012 #ifdef GLX_SGI_cushion
2013
2014 static void
2015 Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
2016 {
2017 (void) dpy;
2018 (void) win;
2019 (void) cushion;
2020 }
2021
2022 #endif
2023
2024
2025 #ifdef GLX_SGIX_video_resize
2026
2027 static int
2028 Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
2029 {
2030 (void) dpy;
2031 (void) screen;
2032 (void) channel;
2033 (void) window;
2034 return 0;
2035 }
2036
2037 static int
2038 Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
2039 {
2040 (void) dpy;
2041 (void) screen;
2042 (void) channel;
2043 (void) x;
2044 (void) y;
2045 (void) w;
2046 (void) h;
2047 return 0;
2048 }
2049
2050 static int
2051 Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
2052 {
2053 (void) dpy;
2054 (void) screen;
2055 (void) channel;
2056 (void) x;
2057 (void) y;
2058 (void) w;
2059 (void) h;
2060 return 0;
2061 }
2062
2063 static int
2064 Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
2065 {
2066 (void) dpy;
2067 (void) screen;
2068 (void) channel;
2069 (void) dx;
2070 (void) dy;
2071 (void) dw;
2072 (void) dh;
2073 return 0;
2074 }
2075
2076 static int
2077 Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
2078 {
2079 (void) dpy;
2080 (void) screen;
2081 (void) channel;
2082 (void) synctype;
2083 return 0;
2084 }
2085
2086 #endif
2087
2088
2089 #if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer)
2090
2091 static Bool
2092 Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
2093 {
2094 (void) dpy;
2095 (void) pbuffer;
2096 (void) params;
2097 (void) dmbuffer;
2098 return False;
2099 }
2100
2101 #endif
2102
2103
2104 #ifdef GLX_SGIX_swap_group
2105
2106 static void
2107 Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
2108 {
2109 (void) dpy;
2110 (void) drawable;
2111 (void) member;
2112 }
2113
2114 #endif
2115
2116
2117 #ifdef GLX_SGIX_swap_barrier
2118
2119 static void
2120 Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
2121 {
2122 (void) dpy;
2123 (void) drawable;
2124 (void) barrier;
2125 }
2126
2127 static Bool
2128 Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
2129 {
2130 (void) dpy;
2131 (void) screen;
2132 (void) max;
2133 return False;
2134 }
2135
2136 #endif
2137
2138
2139 #ifdef GLX_SUN_get_transparent_index
2140
2141 static Status
2142 Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
2143 {
2144 (void) dpy;
2145 (void) overlay;
2146 (void) underlay;
2147 (void) pTransparent;
2148 return 0;
2149 }
2150
2151 #endif
2152
2153
2154 #ifdef GLX_MESA_release_buffers
2155 /*
2156 * Release the depth, stencil, accum buffers attached to a GLXDrawable
2157 * (a window or pixmap) prior to destroying the GLXDrawable.
2158 */
2159 static Bool
2160 Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
2161 {
2162 XMesaBuffer b = XMesaFindBuffer(dpy, d);
2163 if (b) {
2164 XMesaDestroyBuffer(b);
2165 return True;
2166 }
2167 return False;
2168 }
2169 #endif
2170
2171
2172
2173 #ifdef GLX_MESA_set_3dfx_mode
2174 static Bool
2175 Fake_glXSet3DfxModeMESA( int mode )
2176 {
2177 return XMesaSetFXmode( mode );
2178 }
2179 #endif
2180
2181
2182
2183
2184 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
2185 struct _glxapi_table *_mesa_GetGLXDispatchTable(void)
2186 {
2187 static struct _glxapi_table glx;
2188
2189 /* be sure our dispatch table size <= libGL's table */
2190 {
2191 int size = sizeof(struct _glxapi_table) / sizeof(void *);
2192 (void) size;
2193 assert(_glxapi_get_dispatch_table_size() >= size);
2194 }
2195
2196 /* initialize the whole table to no-ops */
2197 _glxapi_set_no_op_table(&glx);
2198
2199 /* now initialize the table with the functions I implement */
2200 glx.ChooseVisual = Fake_glXChooseVisual;
2201 glx.CopyContext = Fake_glXCopyContext;
2202 glx.CreateContext = Fake_glXCreateContext;
2203 glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap;
2204 glx.DestroyContext = Fake_glXDestroyContext;
2205 glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap;
2206 glx.GetConfig = Fake_glXGetConfig;
2207 /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/
2208 /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/
2209 glx.IsDirect = Fake_glXIsDirect;
2210 glx.MakeCurrent = Fake_glXMakeCurrent;
2211 glx.QueryExtension = Fake_glXQueryExtension;
2212 glx.QueryVersion = Fake_glXQueryVersion;
2213 glx.SwapBuffers = Fake_glXSwapBuffers;
2214 glx.UseXFont = Fake_glXUseXFont;
2215 glx.WaitGL = Fake_glXWaitGL;
2216 glx.WaitX = Fake_glXWaitX;
2217
2218 #ifdef GLX_VERSION_1_1
2219 glx.GetClientString = Fake_glXGetClientString;
2220 glx.QueryExtensionsString = Fake_glXQueryExtensionsString;
2221 glx.QueryServerString = Fake_glXQueryServerString;
2222 #endif
2223
2224 #ifdef GLX_VERSION_1_2
2225 /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/
2226 #endif
2227
2228 #ifdef GLX_VERSION_1_3
2229 glx.ChooseFBConfig = Fake_glXChooseFBConfig;
2230 glx.CreateNewContext = Fake_glXCreateNewContext;
2231 glx.CreatePbuffer = Fake_glXCreatePbuffer;
2232 glx.CreatePixmap = Fake_glXCreatePixmap;
2233 glx.CreateWindow = Fake_glXCreateWindow;
2234 glx.DestroyPbuffer = Fake_glXDestroyPbuffer;
2235 glx.DestroyPixmap = Fake_glXDestroyPixmap;
2236 glx.DestroyWindow = Fake_glXDestroyWindow;
2237 /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/
2238 glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib;
2239 glx.GetFBConfigs = Fake_glXGetFBConfigs;
2240 glx.GetSelectedEvent = Fake_glXGetSelectedEvent;
2241 glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig;
2242 glx.MakeContextCurrent = Fake_glXMakeContextCurrent;
2243 glx.QueryContext = Fake_glXQueryContext;
2244 glx.QueryDrawable = Fake_glXQueryDrawable;
2245 glx.SelectEvent = Fake_glXSelectEvent;
2246 #endif
2247
2248 #ifdef GLX_SGI_swap_control
2249 glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI;
2250 #endif
2251
2252 #ifdef GLX_SGI_video_sync
2253 glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI;
2254 glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI;
2255 #endif
2256
2257 #ifdef GLX_SGI_make_current_read
2258 glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI;
2259 glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;
2260 #endif
2261
2262 #if defined(_VL_H) && defined(GLX_SGIX_video_source)
2263 glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX;
2264 glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX;
2265 #endif
2266
2267 #ifdef GLX_EXT_import_context
2268 glx.FreeContextEXT = Fake_glXFreeContextEXT;
2269 glx.GetContextIDEXT = Fake_glXGetContextIDEXT;
2270 glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;
2271 glx.ImportContextEXT = Fake_glXImportContextEXT;
2272 glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT;
2273 #endif
2274
2275 #ifdef GLX_SGIX_fbconfig
2276 glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX;
2277 glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX;
2278 glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX;
2279 glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX;
2280 glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX;
2281 glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX;
2282 #endif
2283
2284 #ifdef GLX_SGIX_pbuffer
2285 glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX;
2286 glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX;
2287 glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX;
2288 glx.SelectEventSGIX = Fake_glXSelectEventSGIX;
2289 glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX;
2290 #endif
2291
2292 #ifdef GLX_SGI_cushion
2293 glx.CushionSGI = Fake_glXCushionSGI;
2294 #endif
2295
2296 #ifdef GLX_SGIX_video_resize
2297 glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX;
2298 glx.ChannelRectSGIX = Fake_glXChannelRectSGIX;
2299 glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX;
2300 glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX;
2301 glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX;
2302 #endif
2303
2304 #if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer)
2305 glx.AssociateDMPbufferSGIX = NULL;
2306 #endif
2307
2308 #ifdef GLX_SGIX_swap_group
2309 glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX;
2310 #endif
2311
2312 #ifdef GLX_SGIX_swap_barrier
2313 glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX;
2314 glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX;
2315 #endif
2316
2317 #ifdef GLX_SUN_get_transparent_index
2318 glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN;
2319 #endif
2320
2321 #ifdef GLX_MESA_copy_sub_buffer
2322 glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA;
2323 #endif
2324
2325 #ifdef GLX_MESA_release_buffers
2326 glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA;
2327 #endif
2328
2329 #ifdef GLX_MESA_pixmap_colormap
2330 glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA;
2331 #endif
2332
2333 #ifdef GLX_MESA_set_3dfx_mode
2334 glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA;
2335 #endif
2336
2337 return &glx;
2338 }