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