blob: 12567fe19c5d5dea152ef43665133b30d6818297 [file] [log] [blame]
jtgafb833d1999-08-19 00:55:39 +00001/* $Id: fakeglx.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 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
30
31/*
32 * A pseudo-GLX implementation to allow OpenGL/GLX programs to work with Mesa.
33 * The Fake_glX*() functions implemented here are called from glxapi.c
34 *
35 * Thanks to the contributors:
36 *
37 * Initial version: Philip Brown (philb@CSUA.Berkeley.EDU)
38 * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
39 * Further visual-handling refinements: Wolfram Gloger
40 * (wmglo@Dent.MED.Uni-Muenchen.DE).
41 *
42 * Notes:
43 * Don't be fooled, stereo isn't supported yet.
44 */
45
46
47
48#ifdef HAVE_CONFIG_H
49#include "conf.h"
50#endif
51
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55#include <X11/Xlib.h>
56#include <X11/Xutil.h>
57#include "GL/gl.h"
58#include "GL/xmesa.h"
59#include "context.h"
60#include "config.h"
61#include "fakeglx.h"
62#include "macros.h"
63#include "types.h"
64#include "xmesaP.h"
65
66
67
68#define DONT_CARE -1
69
70
71
72#define MAX_VISUALS 100
73static XMesaVisual VisualTable[MAX_VISUALS];
74static int NumVisuals = 0;
75
76
77
78/*
79 * This struct and some code fragments borrowed
80 * from Mark Kilgard's GLUT library.
81 */
82typedef struct _OverlayInfo {
83 /* Avoid 64-bit portability problems by being careful to use
84 longs due to the way XGetWindowProperty is specified. Note
85 that these parameters are passed as CARD32s over X
86 protocol. */
87 unsigned long overlay_visual;
88 long transparent_type;
89 long value;
90 long layer;
91} OverlayInfo;
92
93
94
95/* Macro to handle c_class vs class field name in XVisualInfo struct */
96#if defined(__cplusplus) || defined(c_plusplus)
97#define CLASS c_class
98#else
99#define CLASS class
100#endif
101
102
103
104
105/*
106 * Test if the given XVisualInfo is usable for Mesa rendering.
107 */
108static GLboolean is_usable_visual( XVisualInfo *vinfo )
109{
110 switch (vinfo->CLASS) {
111 case StaticGray:
112 case GrayScale:
113 /* Any StaticGray/GrayScale visual works in RGB or CI mode */
114 return GL_TRUE;
115 case StaticColor:
116 case PseudoColor:
117 /* Any StaticColor/PseudoColor visual of at least 4 bits */
118 if (vinfo->depth>=4) {
119 return GL_TRUE;
120 }
121 else {
122 return GL_FALSE;
123 }
124 case TrueColor:
125 case DirectColor:
126 /* Any depth of TrueColor or DirectColor works in RGB mode */
127 return GL_TRUE;
128 default:
129 /* This should never happen */
130 return GL_FALSE;
131 }
132}
133
134
135
136/*
137 * Return the level (overlay, normal, underlay) of a given XVisualInfo.
138 * Input: dpy - the X display
139 * vinfo - the XVisualInfo to test
140 * Return: level of the visual:
141 * 0 = normal planes
142 * >0 = overlay planes
143 * <0 = underlay planes
144 */
145static int level_of_visual( Display *dpy, XVisualInfo *vinfo )
146{
147 Atom overlayVisualsAtom;
148 OverlayInfo *overlay_info = NULL;
149 int numOverlaysPerScreen;
150 Status status;
151 Atom actualType;
152 int actualFormat;
153 unsigned long sizeData, bytesLeft;
154 int i;
155
156 /*
157 * The SERVER_OVERLAY_VISUALS property on the root window contains
158 * a list of overlay visuals. Get that list now.
159 */
160 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
161 if (overlayVisualsAtom == None) {
162 return 0;
163 }
164
165 status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
166 overlayVisualsAtom, 0L, (long) 10000, False,
167 overlayVisualsAtom, &actualType, &actualFormat,
168 &sizeData, &bytesLeft,
169 (unsigned char **) &overlay_info );
170
171 if (status != Success || actualType != overlayVisualsAtom ||
172 actualFormat != 32 || sizeData < 4) {
173 /* something went wrong */
174 XFree((void *) overlay_info);
175 return 0;
176 }
177
178 /* search the overlay visual list for the visual ID of interest */
179 numOverlaysPerScreen = (int) (sizeData / 4);
180 for (i=0;i<numOverlaysPerScreen;i++) {
181 OverlayInfo *ov;
182 ov = overlay_info + i;
183 if (ov->overlay_visual==vinfo->visualid) {
184 /* found the visual */
185 if (/*ov->transparent_type==1 &&*/ ov->layer!=0) {
186 int level = ov->layer;
187 XFree((void *) overlay_info);
188 return level;
189 }
190 else {
191 XFree((void *) overlay_info);
192 return 0;
193 }
194 }
195 }
196
197 /* The visual ID was not found in the overlay list. */
198 XFree((void *) overlay_info);
199 return 0;
200}
201
202
203
204
205/*
206 * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
207 * configuration in our list of GLX visuals.
208 */
209static XMesaVisual
210save_glx_visual( Display *dpy, XVisualInfo *vinfo,
211 GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
212 GLboolean stereoFlag,
213 GLint depth_size, GLint stencil_size,
214 GLint accum_size, GLint level )
215{
216 GLboolean ximageFlag = GL_TRUE;
217 XMesaVisual xmvis;
218 GLint i;
219 GLboolean comparePointers;
220
221 if (dbFlag) {
222 /* Check if the MESA_BACK_BUFFER env var is set */
223 char *backbuffer = getenv("MESA_BACK_BUFFER");
224 if (backbuffer) {
225 if (backbuffer[0]=='p' || backbuffer[0]=='P') {
226 ximageFlag = GL_FALSE;
227 }
228 else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
229 ximageFlag = GL_TRUE;
230 }
231 else {
232 fprintf(stderr, "Mesa: invalid value for MESA_BACK_BUFFER ");
233 fprintf(stderr, "environment variable, using an XImage.\n");
234 }
235 }
236 }
237
238 /* Comparing IDs uses less memory but sometimes fails. */
239 /* XXX revisit this after 3.0 is finished. */
240 if (getenv("MESA_GLX_VISUAL_HACK"))
241 comparePointers = GL_TRUE;
242 else
243 comparePointers = GL_FALSE;
244
245 /* First check if a matching visual is already in the list */
246 for (i=0; i<NumVisuals; i++) {
247 XMesaVisual v = VisualTable[i];
248 if (v->display == dpy
249 && v->level == level
250 && v->ximage_flag == ximageFlag
251 && v->gl_visual->RGBAflag == rgbFlag
252 && v->gl_visual->DBflag == dbFlag
253 && v->gl_visual->StereoFlag == stereoFlag
254 && (v->gl_visual->AlphaBits > 0) == alphaFlag
255 && (v->gl_visual->DepthBits >= depth_size || depth_size == 0)
256 && (v->gl_visual->StencilBits >= stencil_size || stencil_size == 0)
257 && (v->gl_visual->AccumBits >= accum_size || accum_size == 0)) {
258 /* now either compare XVisualInfo pointers or visual IDs */
259 if ((!comparePointers && v->vishandle->visualid == vinfo->visualid)
260 || (comparePointers && v->vishandle == vinfo)) {
261 return v;
262 }
263 }
264 }
265
266 /* Create a new visual and add it to the list. */
267
268 if (NumVisuals>=MAX_VISUALS) {
269 fprintf( stderr, "GLX Error: maximum number of visuals exceeded\n");
270 return NULL;
271 }
272
273 xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
274 stereoFlag, ximageFlag,
275 depth_size, stencil_size, accum_size, level );
276 if (xmvis) {
277 VisualTable[NumVisuals] = xmvis;
278 NumVisuals++;
279 }
280 return xmvis;
281}
282
283
284
285/*
286 * Create a GLX visual from a regular XVisualInfo.
287 */
288static XMesaVisual
289create_glx_visual( Display *dpy, XVisualInfo *visinfo )
290{
291 int vislevel;
292
293 vislevel = level_of_visual( dpy, visinfo );
294 if (vislevel) {
295 /* Configure this visual as a CI, single-buffered overlay */
296 return save_glx_visual( dpy, visinfo,
297 GL_FALSE, /* rgb */
298 GL_FALSE, /* alpha */
299 GL_FALSE, /* double */
300 GL_FALSE, /* stereo */
301 0, /* depth bits */
302 0, /* stencil bits */
303 0, /* accum bits */
304 vislevel /* level */
305 );
306 }
307 else if (is_usable_visual( visinfo )) {
308 /* Configure this visual as RGB, double-buffered, depth-buffered. */
309 /* This is surely wrong for some people's needs but what else */
310 /* can be done? They should use glXChooseVisual(). */
311 return save_glx_visual( dpy, visinfo,
312 GL_TRUE, /* rgb */
313 GL_FALSE, /* alpha */
314 GL_TRUE, /* double */
315 GL_FALSE, /* stereo */
316 8*sizeof(GLdepth),
317 8*sizeof(GLstencil),
318 8*sizeof(GLaccum),
319 0 /* level */
320 );
321 }
322 else {
323 fprintf(stderr,"Mesa: error in glXCreateContext: bad visual\n");
324 return NULL;
325 }
326}
327
328
329
330/*
331 * Find the GLX visual associated with an XVisualInfo.
332 */
333static XMesaVisual
334find_glx_visual( Display *dpy, XVisualInfo *vinfo )
335{
336 int i;
337
338 /* First try to match pointers */
339 for (i=0;i<NumVisuals;i++) {
340 if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
341 return VisualTable[i];
342 }
343 }
344 /* try to match visual id */
345 for (i=0;i<NumVisuals;i++) {
346 if (VisualTable[i]->display==dpy
347 && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
348 return VisualTable[i];
349 }
350 }
351 return NULL;
352}
353
354
355
356/*
357 * Return the transparent pixel value for a GLX visual.
358 * Input: glxvis - the glx_visual
359 * Return: a pixel value or -1 if no transparent pixel
360 */
361static int transparent_pixel( XMesaVisual glxvis )
362{
363 Display *dpy = glxvis->display;
364 XVisualInfo *vinfo = glxvis->visinfo;
365 Atom overlayVisualsAtom;
366 OverlayInfo *overlay_info = NULL;
367 int numOverlaysPerScreen;
368 Status status;
369 Atom actualType;
370 int actualFormat;
371 unsigned long sizeData, bytesLeft;
372 int i;
373
374 /*
375 * The SERVER_OVERLAY_VISUALS property on the root window contains
376 * a list of overlay visuals. Get that list now.
377 */
378 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
379 if (overlayVisualsAtom == None) {
380 return -1;
381 }
382
383 status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
384 overlayVisualsAtom, 0L, (long) 10000, False,
385 overlayVisualsAtom, &actualType, &actualFormat,
386 &sizeData, &bytesLeft,
387 (unsigned char **) &overlay_info );
388
389 if (status != Success || actualType != overlayVisualsAtom ||
390 actualFormat != 32 || sizeData < 4) {
391 /* something went wrong */
392 XFree((void *) overlay_info);
393 return -1;
394 }
395
396 /* search the overlay visual list for the visual ID of interest */
397 numOverlaysPerScreen = (int) (sizeData / 4);
398 for (i=0;i<numOverlaysPerScreen;i++) {
399 OverlayInfo *ov;
400 ov = overlay_info + i;
401 if (ov->overlay_visual==vinfo->visualid) {
402 /* found it! */
403 if (ov->transparent_type==0) {
404 /* type 0 indicates no transparency */
405 XFree((void *) overlay_info);
406 return -1;
407 }
408 else {
409 /* ov->value is the transparent pixel */
410 XFree((void *) overlay_info);
411 return ov->value;
412 }
413 }
414 }
415
416 /* The visual ID was not found in the overlay list. */
417 XFree((void *) overlay_info);
418 return -1;
419}
420
421
422
423/*
424 * Return number of bits set in n.
425 */
426static int bitcount( unsigned long n )
427{
428 int bits;
429 for (bits=0; n>0; n=n>>1) {
430 if (n&1) {
431 bits++;
432 }
433 }
434 return bits;
435}
436
437
438/*
439 * Try to get an X visual which matches the given arguments.
440 */
441static XVisualInfo *get_visual( Display *dpy, int scr,
442 unsigned int depth, int xclass )
443{
444 XVisualInfo temp, *vis;
445 long mask;
446 int n;
447 unsigned int default_depth;
448 int default_class;
449
450 mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
451 temp.screen = scr;
452 temp.depth = depth;
453 temp.CLASS = xclass;
454
455 default_depth = DefaultDepth(dpy,scr);
456 default_class = DefaultVisual(dpy,scr)->CLASS;
457
458 if (depth==default_depth && xclass==default_class) {
459 /* try to get root window's visual */
460 temp.visualid = DefaultVisual(dpy,scr)->visualid;
461 mask |= VisualIDMask;
462 }
463
464 vis = XGetVisualInfo( dpy, mask, &temp, &n );
465
466 /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
467 * An SGI Infinite Reality system, for example, can have 30bpp pixels:
468 * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel.
469 */
470 if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
471 if (bitcount(vis->red_mask) <= 8
472 && bitcount(vis->green_mask) <= 8
473 && bitcount(vis->blue_mask) <= 8) {
474 return vis;
475 }
476 else {
477 XFree((void *) vis);
478 return NULL;
479 }
480 }
481
482 return vis;
483}
484
485
486
487/*
488 * Retrieve the value of the given environment variable and find
489 * the X visual which matches it.
490 * Input: dpy - the display
491 * screen - the screen number
492 * varname - the name of the environment variable
493 * Return: an XVisualInfo pointer to NULL if error.
494 */
495static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname)
496{
497 char value[100], type[100];
498 int depth, xclass = -1;
499 XVisualInfo *vis;
500
501 if (!getenv( varname )) {
502 return NULL;
503 }
504
505 strncpy( value, getenv(varname), 100 );
506 value[99] = 0;
507
508 sscanf( value, "%s %d", type, &depth );
509
510 if (strcmp(type,"TrueColor")==0) xclass = TrueColor;
511 else if (strcmp(type,"DirectColor")==0) xclass = DirectColor;
512 else if (strcmp(type,"PseudoColor")==0) xclass = PseudoColor;
513 else if (strcmp(type,"StaticColor")==0) xclass = StaticColor;
514 else if (strcmp(type,"GrayScale")==0) xclass = GrayScale;
515 else if (strcmp(type,"StaticGray")==0) xclass = StaticGray;
516
517 if (xclass>-1 && depth>0) {
518 vis = get_visual( dpy, scr, depth, xclass );
519 if (vis) {
520 return vis;
521 }
522 }
523
524 fprintf( stderr, "Mesa: GLX unable to find visual class=%s, depth=%d.\n",
525 type, depth );
526 return NULL;
527}
528
529
530
531/*
532 * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
533 * Input: dpy, screen - X display and screen number
534 * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
535 * min_depth - minimum visual depth
536 * preferred_class - preferred GLX visual class or DONT_CARE
537 * Return: pointer to an XVisualInfo or NULL.
538 */
539static XVisualInfo *choose_x_visual( Display *dpy, int screen,
540 GLboolean rgba, int min_depth,
541 int preferred_class )
542{
543 XVisualInfo *vis;
544 int xclass, visclass;
545 int depth;
546
547 if (rgba) {
548 Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
549 /* First see if the MESA_RGB_VISUAL env var is defined */
550 vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
551 if (vis) {
552 return vis;
553 }
554 /* Otherwise, search for a suitable visual */
555 if (preferred_class==DONT_CARE) {
556 for (xclass=0;xclass<6;xclass++) {
557 switch (xclass) {
558 case 0: visclass = TrueColor; break;
559 case 1: visclass = DirectColor; break;
560 case 2: visclass = PseudoColor; break;
561 case 3: visclass = StaticColor; break;
562 case 4: visclass = GrayScale; break;
563 case 5: visclass = StaticGray; break;
564 }
565 if (min_depth==0) {
566 /* start with shallowest */
567 for (depth=0;depth<=32;depth++) {
568 if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
569 /* Special case: try to get 8-bit PseudoColor before */
570 /* 8-bit TrueColor */
571 vis = get_visual( dpy, screen, 8, PseudoColor );
572 if (vis) {
573 return vis;
574 }
575 }
576 vis = get_visual( dpy, screen, depth, visclass );
577 if (vis) {
578 return vis;
579 }
580 }
581 }
582 else {
583 /* start with deepest */
584 for (depth=32;depth>=min_depth;depth--) {
585 if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
586 /* Special case: try to get 8-bit PseudoColor before */
587 /* 8-bit TrueColor */
588 vis = get_visual( dpy, screen, 8, PseudoColor );
589 if (vis) {
590 return vis;
591 }
592 }
593 vis = get_visual( dpy, screen, depth, visclass );
594 if (vis) {
595 return vis;
596 }
597 }
598 }
599 }
600 }
601 else {
602 /* search for a specific visual class */
603 switch (preferred_class) {
604 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
605 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
606 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
607 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
608 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
609 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
610 default: return NULL;
611 }
612 if (min_depth==0) {
613 /* start with shallowest */
614 for (depth=0;depth<=32;depth++) {
615 vis = get_visual( dpy, screen, depth, visclass );
616 if (vis) {
617 return vis;
618 }
619 }
620 }
621 else {
622 /* start with deepest */
623 for (depth=32;depth>=min_depth;depth--) {
624 vis = get_visual( dpy, screen, depth, visclass );
625 if (vis) {
626 return vis;
627 }
628 }
629 }
630 }
631 }
632 else {
633 /* First see if the MESA_CI_VISUAL env var is defined */
634 vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
635 if (vis) {
636 return vis;
637 }
638 /* Otherwise, search for a suitable visual, starting with shallowest */
639 if (preferred_class==DONT_CARE) {
640 for (xclass=0;xclass<4;xclass++) {
641 switch (xclass) {
642 case 0: visclass = PseudoColor; break;
643 case 1: visclass = StaticColor; break;
644 case 2: visclass = GrayScale; break;
645 case 3: visclass = StaticGray; break;
646 }
647 /* try 8-bit up through 16-bit */
648 for (depth=8;depth<=16;depth++) {
649 vis = get_visual( dpy, screen, depth, visclass );
650 if (vis) {
651 return vis;
652 }
653 }
654 /* try min_depth up to 8-bit */
655 for (depth=min_depth;depth<8;depth++) {
656 vis = get_visual( dpy, screen, depth, visclass );
657 if (vis) {
658 return vis;
659 }
660 }
661 }
662 }
663 else {
664 /* search for a specific visual class */
665 switch (preferred_class) {
666 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
667 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
668 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
669 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
670 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
671 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
672 default: return NULL;
673 }
674 /* try 8-bit up through 16-bit */
675 for (depth=8;depth<=16;depth++) {
676 vis = get_visual( dpy, screen, depth, visclass );
677 if (vis) {
678 return vis;
679 }
680 }
681 /* try min_depth up to 8-bit */
682 for (depth=min_depth;depth<8;depth++) {
683 vis = get_visual( dpy, screen, depth, visclass );
684 if (vis) {
685 return vis;
686 }
687 }
688 }
689 }
690
691 /* didn't find a visual */
692 return NULL;
693}
694
695
696
697/*
698 * Find the deepest X over/underlay visual of at least min_depth.
699 * Input: dpy, screen - X display and screen number
700 * level - the over/underlay level
701 * trans_type - transparent pixel type: GLX_NONE_EXT,
702 * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
703 * or DONT_CARE
704 * trans_value - transparent pixel value or DONT_CARE
705 * min_depth - minimum visual depth
706 * preferred_class - preferred GLX visual class or DONT_CARE
707 * Return: pointer to an XVisualInfo or NULL.
708 */
709static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr,
710 int level, int trans_type,
711 int trans_value,
712 int min_depth,
713 int preferred_class )
714{
715 Atom overlayVisualsAtom;
716 OverlayInfo *overlay_info;
717 int numOverlaysPerScreen;
718 Status status;
719 Atom actualType;
720 int actualFormat;
721 unsigned long sizeData, bytesLeft;
722 int i;
723 XVisualInfo *deepvis;
724 int deepest;
725
726 /*DEBUG int tt, tv; */
727
728 switch (preferred_class) {
729 case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break;
730 case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break;
731 case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break;
732 case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break;
733 case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break;
734 case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break;
735 default: preferred_class = DONT_CARE;
736 }
737
738 /*
739 * The SERVER_OVERLAY_VISUALS property on the root window contains
740 * a list of overlay visuals. Get that list now.
741 */
742 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
743 if (overlayVisualsAtom == (Atom) None) {
744 return NULL;
745 }
746
747 status = XGetWindowProperty(dpy, RootWindow( dpy, scr ),
748 overlayVisualsAtom, 0L, (long) 10000, False,
749 overlayVisualsAtom, &actualType, &actualFormat,
750 &sizeData, &bytesLeft,
751 (unsigned char **) &overlay_info );
752
753 if (status != Success || actualType != overlayVisualsAtom ||
754 actualFormat != 32 || sizeData < 4) {
755 /* something went wrong */
756 return NULL;
757 }
758
759 /* Search for the deepest overlay which satisifies all criteria. */
760 deepest = min_depth;
761 deepvis = NULL;
762
763 numOverlaysPerScreen = (int) (sizeData / 4);
764 for (i=0;i<numOverlaysPerScreen;i++) {
765 XVisualInfo *vislist, vistemplate;
766 int count;
767 OverlayInfo *ov;
768 ov = overlay_info + i;
769
770 if (ov->layer!=level) {
771 /* failed overlay level criteria */
772 continue;
773 }
774 if (!(trans_type==DONT_CARE
775 || (trans_type==GLX_TRANSPARENT_INDEX_EXT
776 && ov->transparent_type>0)
777 || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
778 /* failed transparent pixel type criteria */
779 continue;
780 }
781 if (trans_value!=DONT_CARE && trans_value!=ov->value) {
782 /* failed transparent pixel value criteria */
783 continue;
784 }
785
786 /* get XVisualInfo and check the depth */
787 vistemplate.visualid = ov->overlay_visual;
788 vistemplate.screen = scr;
789 vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
790 &vistemplate, &count );
791
792 if (count!=1) {
793 /* something went wrong */
794 continue;
795 }
796 if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
797 /* wrong visual class */
798 continue;
799 }
800
801 if (deepvis==NULL || vislist->depth > deepest) {
802 /* YES! found a satisfactory visual */
803 if (deepvis) {
804 free( deepvis );
805 }
806 deepest = vislist->depth;
807 deepvis = vislist;
808 /* DEBUG tt = ov->transparent_type;*/
809 /* DEBUG tv = ov->value; */
810 }
811 }
812
813/*DEBUG
814 if (deepvis) {
815 printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n",
816 deepvis->visualid, level, deepvis->depth, tt, tv );
817 }
818*/
819 return deepvis;
820}
821
822
823
824XVisualInfo *Fake_glXChooseVisual( Display *dpy, int screen, int *list )
825{
826 int *parselist;
827 XVisualInfo *vis;
828 int min_ci = 0;
829 int min_red=0, min_green=0, min_blue=0;
830 GLboolean rgb_flag = GL_FALSE;
831 GLboolean alpha_flag = GL_FALSE;
832 GLboolean double_flag = GL_FALSE;
833 GLboolean stereo_flag = GL_FALSE;
834 GLint depth_size = 0;
835 GLint stencil_size = 0;
836 GLint accum_size = 0;
837 int level = 0;
838 int visual_type = DONT_CARE;
839 int trans_type = DONT_CARE;
840 int trans_value = DONT_CARE;
841
842 parselist = list;
843
844 while (*parselist) {
845
846 switch (*parselist) {
847 case GLX_USE_GL:
848 /* ignore */
849 parselist++;
850 break;
851 case GLX_BUFFER_SIZE:
852 parselist++;
853 min_ci = *parselist++;
854 break;
855 case GLX_LEVEL:
856 parselist++;
857 level = *parselist++;
858 break;
859 case GLX_RGBA:
860 rgb_flag = GL_TRUE;
861 parselist++;
862 break;
863 case GLX_DOUBLEBUFFER:
864 double_flag = GL_TRUE;
865 parselist++;
866 break;
867 case GLX_STEREO:
868 stereo_flag = GL_TRUE;
869 return NULL;
870 case GLX_AUX_BUFFERS:
871 /* ignore */
872 parselist++;
873 parselist++;
874 break;
875 case GLX_RED_SIZE:
876 parselist++;
877 min_red = *parselist++;
878 break;
879 case GLX_GREEN_SIZE:
880 parselist++;
881 min_green = *parselist++;
882 break;
883 case GLX_BLUE_SIZE:
884 parselist++;
885 min_blue = *parselist++;
886 break;
887 case GLX_ALPHA_SIZE:
888 parselist++;
889 {
890 GLint size = *parselist++;
891 alpha_flag = size>0 ? 1 : 0;
892 }
893 break;
894 case GLX_DEPTH_SIZE:
895 parselist++;
896 depth_size = *parselist++;
897 break;
898 case GLX_STENCIL_SIZE:
899 parselist++;
900 stencil_size = *parselist++;
901 break;
902 case GLX_ACCUM_RED_SIZE:
903 case GLX_ACCUM_GREEN_SIZE:
904 case GLX_ACCUM_BLUE_SIZE:
905 case GLX_ACCUM_ALPHA_SIZE:
906 parselist++;
907 {
908 GLint size = *parselist++;
909 accum_size = MAX2( accum_size, size );
910 }
911 break;
912
913 /*
914 * GLX_EXT_visual_info extension
915 */
916 case GLX_X_VISUAL_TYPE_EXT:
917 parselist++;
918 visual_type = *parselist++;
919 break;
920 case GLX_TRANSPARENT_TYPE_EXT:
921 parselist++;
922 trans_type = *parselist++;
923 break;
924 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
925 parselist++;
926 trans_value = *parselist++;
927 break;
928 case GLX_TRANSPARENT_RED_VALUE_EXT:
929 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
930 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
931 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
932 /* ignore */
933 parselist++;
934 parselist++;
935 break;
936
937 case None:
938 break;
939 default:
940 /* undefined attribute */
941 return NULL;
942 }
943 }
944
945 /*
946 * Since we're only simulating the GLX extension this function will never
947 * find any real GL visuals. Instead, all we can do is try to find an RGB
948 * or CI visual of appropriate depth. Other requested attributes such as
949 * double buffering, depth buffer, etc. will be associated with the X
950 * visual and stored in the VisualTable[].
951 */
952 if (level==0) {
953 /* normal color planes */
954 if (rgb_flag) {
955 /* Get an RGB visual */
956 int min_rgb = min_red + min_green + min_blue;
957 if (min_rgb>1 && min_rgb<8) {
958 /* a special case to be sure we can get a monochrome visual */
959 min_rgb = 1;
960 }
961 vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
962 }
963 else {
964 /* Get a color index visual */
965 vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
966 accum_size = 0;
967 }
968 }
969 else {
970 /* over/underlay planes */
971 vis = choose_x_overlay_visual( dpy, screen, level, trans_type,
972 trans_value, min_ci, visual_type );
973 }
974
975 if (vis) {
976 if (!save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
977 stereo_flag,
978 depth_size, stencil_size, accum_size, level ))
979 return NULL;
980 }
981
982 return vis;
983}
984
985
986
987
988GLXContext Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
989 GLXContext share_list, Bool direct )
990{
991 XMesaVisual glxvis;
992 XMesaContext xmctx;
993
994 /* deallocate unused windows/buffers */
995 XMesaGarbageCollect();
996
997 glxvis = find_glx_visual( dpy, visinfo );
998 if (!glxvis) {
999 /* This visual wasn't found with glXChooseVisual() */
1000 glxvis = create_glx_visual( dpy, visinfo );
1001 if (!glxvis) {
1002 /* unusable visual */
1003 return NULL;
1004 }
1005 }
1006
1007 xmctx = XMesaCreateContext( glxvis, (XMesaContext) share_list );
1008 if (xmctx) {
1009 /* set the direct/indirect flag */
1010 xmctx->direct = direct;
1011 }
1012 return (GLXContext) xmctx;
1013}
1014
1015
1016static GLXDrawable MakeCurrent_PrevDrawable = 0;
1017static GLXContext MakeCurrent_PrevContext = 0;
1018static XMesaBuffer MakeCurrent_PrevBuffer = 0;
1019
1020Bool Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
1021{
1022 if (ctx && drawable) {
1023 XMesaBuffer buffer;
1024
1025 if (drawable==MakeCurrent_PrevDrawable && ctx==MakeCurrent_PrevContext) {
1026 buffer = MakeCurrent_PrevBuffer;
1027 }
1028 else {
1029 buffer = XMesaFindBuffer( dpy, drawable );
1030 }
1031 if (!buffer) {
1032 /* drawable must be a new window! */
1033 buffer = XMesaCreateWindowBuffer2( ctx->xm_visual, drawable, ctx );
1034 if (!buffer) {
1035 /* Out of memory, or context/drawable depth mismatch */
1036 return False;
1037 }
1038 }
1039 MakeCurrent_PrevContext = ctx;
1040 MakeCurrent_PrevDrawable = drawable;
1041 MakeCurrent_PrevBuffer = buffer;
1042
1043 /* Now make current! */
1044 return (Bool) XMesaMakeCurrent( (XMesaContext) ctx, buffer );
1045 }
1046 else if (!ctx && !drawable) {
1047 /* release current context w/out assigning new one. */
1048 XMesaMakeCurrent( NULL, NULL );
1049 MakeCurrent_PrevContext = 0;
1050 MakeCurrent_PrevDrawable = 0;
1051 MakeCurrent_PrevBuffer = 0;
1052 return True;
1053 }
1054 else {
1055 /* ctx XOR drawable is NULL, this is an error */
1056 return False;
1057 }
1058}
1059
1060
1061
1062GLXPixmap Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
1063 Pixmap pixmap )
1064{
1065 XMesaVisual v;
1066 XMesaBuffer b;
1067
1068 v = find_glx_visual( dpy, visinfo );
1069 if (!v) {
1070 v = create_glx_visual( dpy, visinfo );
1071 if (!v) {
1072 /* unusable visual */
1073 return 0;
1074 }
1075 }
1076
1077 b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
1078 if (!b) {
1079 return 0;
1080 }
1081 return b->frontbuffer;
1082}
1083
1084
1085#ifdef GLX_MESA_pixmap_colormap
1086
1087GLXPixmap Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
1088 Pixmap pixmap, Colormap cmap )
1089{
1090 XMesaVisual v;
1091 XMesaBuffer b;
1092
1093 v = find_glx_visual( dpy, visinfo );
1094 if (!v) {
1095 v = create_glx_visual( dpy, visinfo );
1096 if (!v) {
1097 /* unusable visual */
1098 return 0;
1099 }
1100 }
1101
1102 b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
1103 if (!b) {
1104 return 0;
1105 }
1106 return b->frontbuffer;
1107}
1108
1109#endif
1110
1111
1112void Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
1113{
1114 XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
1115 if (b) {
1116 XMesaDestroyBuffer(b);
1117 }
1118 else if (getenv("MESA_DEBUG")) {
1119 fprintf( stderr, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
1120 }
1121}
1122
1123
1124void Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
1125 GLuint mask )
1126{
1127 XMesaContext xm_src = (XMesaContext) src;
1128 XMesaContext xm_dst = (XMesaContext) dst;
1129 (void) dpy;
1130 gl_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, mask );
1131}
1132
1133
1134
1135Bool Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
1136{
1137 /* Mesa's GLX isn't really an X extension but we try to act like one. */
1138 (void) dpy;
1139 (void) errorb;
1140 (void) event;
1141 return True;
1142}
1143
1144
1145void _kw_ungrab_all( Display *dpy )
1146{
1147 XUngrabPointer( dpy, CurrentTime );
1148 XUngrabKeyboard( dpy, CurrentTime );
1149}
1150
1151
1152void Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
1153{
1154 (void) dpy;
1155 MakeCurrent_PrevContext = 0;
1156 MakeCurrent_PrevDrawable = 0;
1157 MakeCurrent_PrevBuffer = 0;
1158 XMesaDestroyContext( (XMesaContext) ctx );
1159 XMesaGarbageCollect();
1160}
1161
1162
1163
1164Bool Fake_glXIsDirect( Display *dpy, GLXContext ctx )
1165{
1166 (void) dpy;
1167 return ((XMesaContext) ctx)->direct;
1168}
1169
1170
1171
1172void Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
1173{
1174 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1175 static GLXDrawable last = 0;
1176 static Window window = 0;
1177 if (drawable != last && 0) {
1178 XSetWindowAttributes cwa;
1179
1180 _kw_ungrab_all( dpy );
1181 cwa.override_redirect = 0;
1182 XChangeWindowAttributes( dpy, drawable, CWOverrideRedirect,
1183 &cwa );
1184/* printf("KW: Ungrab display %s\n", DisplayString(dpy)); */
1185
1186
1187/* last = drawable; */
1188
1189
1190 if (!window) {
1191 XSetWindowAttributes cwa;
1192
1193 if ((window = XCreateSimpleWindow( dpy,
1194 RootWindow( dpy, 0 ),
1195 10,10,100,100, 0,
1196 WhitePixel( dpy, 0 ),
1197 BlackPixel( dpy, 0 ))) == 0)
1198 {
1199 printf("Failed to open radar window\n");
1200 abort();
1201 }
1202
1203 cwa.event_mask = (PointerMotionMask |
1204 ButtonPressMask |
1205 ButtonReleaseMask |
1206 KeyPressMask |
1207 KeyReleaseMask |
1208 ExposureMask );
1209
1210 XChangeWindowAttributes( dpy, window,
1211 CWEventMask,
1212 &cwa );
1213
1214 XMapWindow( dpy, window );
1215 XFlush( dpy );
1216 }
1217 }
1218 if (buffer) {
1219 XMesaSwapBuffers(buffer);
1220 }
1221 else if (getenv("MESA_DEBUG")) {
1222 fprintf(stderr, "Mesa Warning: glXSwapBuffers: invalid drawable\n");
1223 }
1224}
1225
1226
1227void Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
1228 int x, int y, int width, int height )
1229{
1230 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1231 if (buffer) {
1232 XMesaCopySubBuffer(buffer, x, y, width, height);
1233 }
1234 else if (getenv("MESA_DEBUG")) {
1235 fprintf(stderr, "Mesa Warning: glXCopySubBufferMESA: invalid drawable\n");
1236 }
1237}
1238
1239
1240
1241Bool Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
1242{
1243 (void) dpy;
1244 /* Return GLX version, not Mesa version */
1245 *maj = 1;
1246 *min = 1;
1247 return True;
1248}
1249
1250
1251
1252/*
1253 * Query the GLX attributes of the given XVisualInfo.
1254 */
1255int Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
1256 int attrib, int *value )
1257{
1258 XMesaVisual glxvis;
1259
1260 glxvis = find_glx_visual( dpy, visinfo );
1261 if (!glxvis) {
1262 /* this visual wasn't obtained with glXChooseVisual */
1263 glxvis = create_glx_visual( dpy, visinfo );
1264 if (!glxvis) {
1265 /* this visual can't be used for GL rendering */
1266 if (attrib==GLX_USE_GL) {
1267 *value = (int) False;
1268 return 0;
1269 }
1270 else {
1271 /*fprintf( stderr, "Mesa: Error in glXGetConfig: bad visual\n");*/
1272 return GLX_BAD_VISUAL;
1273 }
1274 }
1275 }
1276
1277 switch(attrib) {
1278 case GLX_USE_GL:
1279 *value = (int) True;
1280 return 0;
1281 case GLX_BUFFER_SIZE:
1282 *value = visinfo->depth;
1283 return 0;
1284 case GLX_LEVEL:
1285 *value = glxvis->level;
1286 return 0;
1287 case GLX_RGBA:
1288 if (glxvis->gl_visual->RGBAflag) {
1289 *value = True;
1290 }
1291 else {
1292 *value = False;
1293 }
1294 return 0;
1295 case GLX_DOUBLEBUFFER:
1296 *value = (int) glxvis->gl_visual->DBflag;
1297 return 0;
1298 case GLX_STEREO:
1299 *value = (int) glxvis->gl_visual->StereoFlag;
1300 return 0;
1301 case GLX_AUX_BUFFERS:
1302 *value = (int) False;
1303 return 0;
1304 case GLX_RED_SIZE:
1305 *value = glxvis->gl_visual->RedBits;
1306 return 0;
1307 case GLX_GREEN_SIZE:
1308 *value = glxvis->gl_visual->GreenBits;
1309 return 0;
1310 case GLX_BLUE_SIZE:
1311 *value = glxvis->gl_visual->BlueBits;
1312 return 0;
1313 case GLX_ALPHA_SIZE:
1314 *value = glxvis->gl_visual->AlphaBits;
1315 return 0;
1316 case GLX_DEPTH_SIZE:
1317 *value = glxvis->gl_visual->DepthBits;
1318 return 0;
1319 case GLX_STENCIL_SIZE:
1320 *value = glxvis->gl_visual->StencilBits;
1321 return 0;
1322 case GLX_ACCUM_RED_SIZE:
1323 case GLX_ACCUM_GREEN_SIZE:
1324 case GLX_ACCUM_BLUE_SIZE:
1325 *value = glxvis->gl_visual->AccumBits;
1326 return 0;
1327 case GLX_ACCUM_ALPHA_SIZE:
1328 if (glxvis->gl_visual->AlphaBits > 0)
1329 *value = glxvis->gl_visual->AccumBits;
1330 else
1331 *value = 0;
1332 return 0;
1333
1334 /*
1335 * GLX_EXT_visual_info extension
1336 */
1337 case GLX_X_VISUAL_TYPE_EXT:
1338 switch (glxvis->visinfo->CLASS) {
1339 case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0;
1340 case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0;
1341 case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0;
1342 case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0;
1343 case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0;
1344 case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0;
1345 }
1346 return 0;
1347 case GLX_TRANSPARENT_TYPE_EXT:
1348 if (glxvis->level==0) {
1349 /* normal planes */
1350 *value = GLX_NONE_EXT;
1351 }
1352 else if (glxvis->level>0) {
1353 /* overlay */
1354 if (glxvis->gl_visual->RGBAflag) {
1355 *value = GLX_TRANSPARENT_RGB_EXT;
1356 }
1357 else {
1358 *value = GLX_TRANSPARENT_INDEX_EXT;
1359 }
1360 }
1361 else if (glxvis->level<0) {
1362 /* underlay */
1363 *value = GLX_NONE_EXT;
1364 }
1365 return 0;
1366 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
1367 {
1368 int pixel = transparent_pixel( glxvis );
1369 if (pixel>=0) {
1370 *value = pixel;
1371 }
1372 /* else undefined */
1373 }
1374 return 0;
1375 case GLX_TRANSPARENT_RED_VALUE_EXT:
1376 /* undefined */
1377 return 0;
1378 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
1379 /* undefined */
1380 return 0;
1381 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
1382 /* undefined */
1383 return 0;
1384 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
1385 /* undefined */
1386 return 0;
1387
1388 /*
1389 * Extensions
1390 */
1391 default:
1392 return GLX_BAD_ATTRIBUTE;
1393 }
1394}
1395
1396
1397
1398GLXContext Fake_glXGetCurrentContext( void )
1399{
1400 return (GLXContext) XMesaGetCurrentContext();
1401}
1402
1403
1404
1405GLXDrawable Fake_glXGetCurrentDrawable( void )
1406{
1407 XMesaBuffer b = XMesaGetCurrentBuffer();
1408 if (b) {
1409 return b->frontbuffer;
1410 }
1411 else {
1412 return 0;
1413 }
1414}
1415
1416
1417void Fake_glXWaitGL( void )
1418{
1419 XMesaContext xmesa = XMesaGetCurrentContext();
1420 XMesaFlush( xmesa );
1421}
1422
1423
1424
1425void Fake_glXWaitX( void )
1426{
1427 XMesaContext xmesa = XMesaGetCurrentContext();
1428 XMesaFlush( xmesa );
1429}
1430
1431
1432
1433#define EXTENSIONS "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync"
1434
1435
1436/* GLX 1.1 and later */
1437const char *Fake_glXQueryExtensionsString( Display *dpy, int screen )
1438{
1439 static char *extensions = EXTENSIONS;
1440 (void) dpy;
1441 (void) screen;
1442 return extensions;
1443}
1444
1445
1446
1447/* GLX 1.1 and later */
1448const char *Fake_glXQueryServerString( Display *dpy, int screen, int name )
1449{
1450 static char *extensions = EXTENSIONS;
1451 static char *vendor = "Brian Paul";
1452 static char *version = "1.1 Mesa 3.0";
1453
1454 (void) dpy;
1455 (void) screen;
1456
1457 switch (name) {
1458 case GLX_EXTENSIONS:
1459 return extensions;
1460 case GLX_VENDOR:
1461 return vendor;
1462 case GLX_VERSION:
1463 return version;
1464 default:
1465 return NULL;
1466 }
1467}
1468
1469
1470
1471/* GLX 1.1 and later */
1472const char *Fake_glXGetClientString( Display *dpy, int name )
1473{
1474 static char *extensions = EXTENSIONS;
1475 static char *vendor = "Brian Paul";
1476 static char *version = "1.1 Mesa 3.0";
1477
1478 (void) dpy;
1479
1480 switch (name) {
1481 case GLX_EXTENSIONS:
1482 return extensions;
1483 case GLX_VENDOR:
1484 return vendor;
1485 case GLX_VERSION:
1486 return version;
1487 default:
1488 return NULL;
1489 }
1490}
1491
1492
1493
1494/*
1495 * Release the depth, stencil, accum buffers attached to a GLXDrawable
1496 * (a window or pixmap) prior to destroying the GLXDrawable.
1497 */
1498Bool Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
1499{
1500 XMesaBuffer b = XMesaFindBuffer(dpy, d);
1501 if (b) {
1502 XMesaDestroyBuffer(b);
1503 return True;
1504 }
1505 return False;
1506}
1507
1508
1509/* Silence compiler warnings */
1510void Fake_glXDummyFunc( void )
1511{
1512 (void) kernel8;
1513 (void) DitherValues;
1514 (void) HPCR_DRGB;
1515 (void) kernel1;
1516}