silence some warnings
[mesa.git] / src / mesa / drivers / x11 / fakeglx.c
1 /* $Id: fakeglx.c,v 1.26 2000/03/17 15:33:09 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
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 (philb@CSUA.Berkeley.EDU)
35 * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
36 * Further visual-handling refinements: Wolfram Gloger
37 * (wmglo@Dent.MED.Uni-Muenchen.DE).
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 "types.h"
52 #include "xmesaP.h"
53
54
55 /* This indicates the client-side GLX API and GLX encoder version. */
56 #define CLIENT_MAJOR_VERSION 1
57 #define CLIENT_MINOR_VERSION 2
58
59 /* This indicates the server-side GLX decoder version.
60 * GLX 1.3 indicates OpenGL 1.2 support
61 */
62 #define SERVER_MAJOR_VERSION 1
63 #define SERVER_MINOR_VERSION 3
64
65 /* This is appended onto the glXGetClient/ServerString version strings. */
66 #define MESA_GLX_VERSION "Mesa 3.3"
67
68 /* Who implemented this GLX? */
69 #define VENDOR "Brian Paul"
70
71
72
73 /* Silence compiler warnings */
74 extern void Fake_glXDummyFunc( void );
75 void Fake_glXDummyFunc( void )
76 {
77 (void) kernel8;
78 (void) DitherValues;
79 (void) HPCR_DRGB;
80 (void) kernel1;
81 }
82
83
84
85 #define DONT_CARE -1
86
87
88
89 #define MAX_VISUALS 100
90 static XMesaVisual VisualTable[MAX_VISUALS];
91 static int NumVisuals = 0;
92
93
94
95 /*
96 * This struct and some code fragments borrowed
97 * from Mark Kilgard's GLUT library.
98 */
99 typedef struct _OverlayInfo {
100 /* Avoid 64-bit portability problems by being careful to use
101 longs due to the way XGetWindowProperty is specified. Note
102 that these parameters are passed as CARD32s over X
103 protocol. */
104 unsigned long overlay_visual;
105 long transparent_type;
106 long value;
107 long layer;
108 } OverlayInfo;
109
110
111
112 /* Macro to handle c_class vs class field name in XVisualInfo struct */
113 #if defined(__cplusplus) || defined(c_plusplus)
114 #define CLASS c_class
115 #else
116 #define CLASS class
117 #endif
118
119
120
121
122 /*
123 * Test if the given XVisualInfo is usable for Mesa rendering.
124 */
125 static GLboolean is_usable_visual( XVisualInfo *vinfo )
126 {
127 switch (vinfo->CLASS) {
128 case StaticGray:
129 case GrayScale:
130 /* Any StaticGray/GrayScale visual works in RGB or CI mode */
131 return GL_TRUE;
132 case StaticColor:
133 case PseudoColor:
134 /* Any StaticColor/PseudoColor visual of at least 4 bits */
135 if (vinfo->depth>=4) {
136 return GL_TRUE;
137 }
138 else {
139 return GL_FALSE;
140 }
141 case TrueColor:
142 case DirectColor:
143 /* Any depth of TrueColor or DirectColor works in RGB mode */
144 return GL_TRUE;
145 default:
146 /* This should never happen */
147 return GL_FALSE;
148 }
149 }
150
151
152
153 /*
154 * Return the level (overlay, normal, underlay) of a given XVisualInfo.
155 * Input: dpy - the X display
156 * vinfo - the XVisualInfo to test
157 * Return: level of the visual:
158 * 0 = normal planes
159 * >0 = overlay planes
160 * <0 = underlay planes
161 */
162 static int level_of_visual( Display *dpy, XVisualInfo *vinfo )
163 {
164 Atom overlayVisualsAtom;
165 OverlayInfo *overlay_info = NULL;
166 int numOverlaysPerScreen;
167 Status status;
168 Atom actualType;
169 int actualFormat;
170 unsigned long sizeData, bytesLeft;
171 int i;
172
173 /*
174 * The SERVER_OVERLAY_VISUALS property on the root window contains
175 * a list of overlay visuals. Get that list now.
176 */
177 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
178 if (overlayVisualsAtom == None) {
179 return 0;
180 }
181
182 status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
183 overlayVisualsAtom, 0L, (long) 10000, False,
184 overlayVisualsAtom, &actualType, &actualFormat,
185 &sizeData, &bytesLeft,
186 (unsigned char **) &overlay_info );
187
188 if (status != Success || actualType != overlayVisualsAtom ||
189 actualFormat != 32 || sizeData < 4) {
190 /* something went wrong */
191 XFree((void *) overlay_info);
192 return 0;
193 }
194
195 /* search the overlay visual list for the visual ID of interest */
196 numOverlaysPerScreen = (int) (sizeData / 4);
197 for (i=0;i<numOverlaysPerScreen;i++) {
198 OverlayInfo *ov;
199 ov = overlay_info + i;
200 if (ov->overlay_visual==vinfo->visualid) {
201 /* found the visual */
202 if (/*ov->transparent_type==1 &&*/ ov->layer!=0) {
203 int level = ov->layer;
204 XFree((void *) overlay_info);
205 return level;
206 }
207 else {
208 XFree((void *) overlay_info);
209 return 0;
210 }
211 }
212 }
213
214 /* The visual ID was not found in the overlay list. */
215 XFree((void *) overlay_info);
216 return 0;
217 }
218
219
220
221
222 /*
223 * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
224 * configuration in our list of GLX visuals.
225 */
226 static XMesaVisual
227 save_glx_visual( Display *dpy, XVisualInfo *vinfo,
228 GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
229 GLboolean stereoFlag,
230 GLint depth_size, GLint stencil_size,
231 GLint accum_size, GLint level )
232 {
233 GLboolean ximageFlag = GL_TRUE;
234 XMesaVisual xmvis;
235 GLint i;
236 GLboolean comparePointers;
237
238 if (dbFlag) {
239 /* Check if the MESA_BACK_BUFFER env var is set */
240 char *backbuffer = getenv("MESA_BACK_BUFFER");
241 if (backbuffer) {
242 if (backbuffer[0]=='p' || backbuffer[0]=='P') {
243 ximageFlag = GL_FALSE;
244 }
245 else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
246 ximageFlag = GL_TRUE;
247 }
248 else {
249 fprintf(stderr, "Mesa: invalid value for MESA_BACK_BUFFER ");
250 fprintf(stderr, "environment variable, using an XImage.\n");
251 }
252 }
253 }
254
255 /* Comparing IDs uses less memory but sometimes fails. */
256 /* XXX revisit this after 3.0 is finished. */
257 if (getenv("MESA_GLX_VISUAL_HACK"))
258 comparePointers = GL_TRUE;
259 else
260 comparePointers = GL_FALSE;
261
262 /* First check if a matching visual is already in the list */
263 for (i=0; i<NumVisuals; i++) {
264 XMesaVisual v = VisualTable[i];
265 if (v->display == dpy
266 && v->level == level
267 && v->ximage_flag == ximageFlag
268 && v->gl_visual->RGBAflag == rgbFlag
269 && v->gl_visual->DBflag == dbFlag
270 && v->gl_visual->StereoFlag == stereoFlag
271 && (v->gl_visual->AlphaBits > 0) == alphaFlag
272 && (v->gl_visual->DepthBits >= depth_size || depth_size == 0)
273 && (v->gl_visual->StencilBits >= stencil_size || stencil_size == 0)
274 && (v->gl_visual->AccumBits >= accum_size || accum_size == 0)) {
275 /* now either compare XVisualInfo pointers or visual IDs */
276 if ((!comparePointers && v->visinfo->visualid == vinfo->visualid)
277 || (comparePointers && v->vishandle == vinfo)) {
278 return v;
279 }
280 }
281 }
282
283 /* Create a new visual and add it to the list. */
284
285 if (NumVisuals>=MAX_VISUALS) {
286 fprintf( stderr, "GLX Error: maximum number of visuals exceeded\n");
287 return NULL;
288 }
289
290 xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
291 stereoFlag, ximageFlag,
292 depth_size, stencil_size, accum_size, level );
293 if (xmvis) {
294 VisualTable[NumVisuals] = xmvis;
295 NumVisuals++;
296 }
297 return xmvis;
298 }
299
300
301
302 /*
303 * Create a GLX visual from a regular XVisualInfo.
304 * This is called when Fake GLX is given an XVisualInfo which wasn't
305 * returned by glXChooseVisual. Since this is the first time we're
306 * considering this visual we'll take a guess at reasonable values
307 * for depth buffer size, stencil size, accum size, etc.
308 * This is the best we can do with a client-side emulation of GLX.
309 */
310 static XMesaVisual
311 create_glx_visual( Display *dpy, XVisualInfo *visinfo )
312 {
313 int vislevel;
314
315 vislevel = level_of_visual( dpy, visinfo );
316 if (vislevel) {
317 /* Configure this visual as a CI, single-buffered overlay */
318 return save_glx_visual( dpy, visinfo,
319 GL_FALSE, /* rgb */
320 GL_FALSE, /* alpha */
321 GL_FALSE, /* double */
322 GL_FALSE, /* stereo */
323 0, /* depth bits */
324 0, /* stencil bits */
325 0, /* accum bits */
326 vislevel /* level */
327 );
328 }
329 else if (is_usable_visual( visinfo )) {
330 /* Configure this visual as RGB, double-buffered, depth-buffered. */
331 /* This is surely wrong for some people's needs but what else */
332 /* can be done? They should use glXChooseVisual(). */
333 return save_glx_visual( dpy, visinfo,
334 GL_TRUE, /* rgb */
335 GL_FALSE, /* alpha */
336 GL_TRUE, /* double */
337 GL_FALSE, /* stereo */
338 DEFAULT_SOFTWARE_DEPTH_BITS,
339 8 * sizeof(GLstencil),
340 8 * sizeof(GLaccum),
341 0 /* level */
342 );
343 }
344 else {
345 fprintf(stderr,"Mesa: error in glXCreateContext: bad visual\n");
346 return NULL;
347 }
348 }
349
350
351
352 /*
353 * Find the GLX visual associated with an XVisualInfo.
354 */
355 static XMesaVisual
356 find_glx_visual( Display *dpy, XVisualInfo *vinfo )
357 {
358 int i;
359
360 /* First try to match pointers */
361 for (i=0;i<NumVisuals;i++) {
362 if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
363 return VisualTable[i];
364 }
365 }
366 /* try to match visual id */
367 for (i=0;i<NumVisuals;i++) {
368 if (VisualTable[i]->display==dpy
369 && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
370 return VisualTable[i];
371 }
372 }
373 return NULL;
374 }
375
376
377
378 /*
379 * Return the transparent pixel value for a GLX visual.
380 * Input: glxvis - the glx_visual
381 * Return: a pixel value or -1 if no transparent pixel
382 */
383 static int transparent_pixel( XMesaVisual glxvis )
384 {
385 Display *dpy = glxvis->display;
386 XVisualInfo *vinfo = glxvis->visinfo;
387 Atom overlayVisualsAtom;
388 OverlayInfo *overlay_info = NULL;
389 int numOverlaysPerScreen;
390 Status status;
391 Atom actualType;
392 int actualFormat;
393 unsigned long sizeData, bytesLeft;
394 int i;
395
396 /*
397 * The SERVER_OVERLAY_VISUALS property on the root window contains
398 * a list of overlay visuals. Get that list now.
399 */
400 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
401 if (overlayVisualsAtom == None) {
402 return -1;
403 }
404
405 status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
406 overlayVisualsAtom, 0L, (long) 10000, False,
407 overlayVisualsAtom, &actualType, &actualFormat,
408 &sizeData, &bytesLeft,
409 (unsigned char **) &overlay_info );
410
411 if (status != Success || actualType != overlayVisualsAtom ||
412 actualFormat != 32 || sizeData < 4) {
413 /* something went wrong */
414 XFree((void *) overlay_info);
415 return -1;
416 }
417
418 /* search the overlay visual list for the visual ID of interest */
419 numOverlaysPerScreen = (int) (sizeData / 4);
420 for (i=0;i<numOverlaysPerScreen;i++) {
421 OverlayInfo *ov;
422 ov = overlay_info + i;
423 if (ov->overlay_visual==vinfo->visualid) {
424 /* found it! */
425 if (ov->transparent_type==0) {
426 /* type 0 indicates no transparency */
427 XFree((void *) overlay_info);
428 return -1;
429 }
430 else {
431 /* ov->value is the transparent pixel */
432 XFree((void *) overlay_info);
433 return ov->value;
434 }
435 }
436 }
437
438 /* The visual ID was not found in the overlay list. */
439 XFree((void *) overlay_info);
440 return -1;
441 }
442
443
444
445 /*
446 * Return number of bits set in n.
447 */
448 static int bitcount( unsigned long n )
449 {
450 int bits;
451 for (bits=0; n>0; n=n>>1) {
452 if (n&1) {
453 bits++;
454 }
455 }
456 return bits;
457 }
458
459
460 /*
461 * Try to get an X visual which matches the given arguments.
462 */
463 static XVisualInfo *get_visual( Display *dpy, int scr,
464 unsigned int depth, int xclass )
465 {
466 XVisualInfo temp, *vis;
467 long mask;
468 int n;
469 unsigned int default_depth;
470 int default_class;
471
472 mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
473 temp.screen = scr;
474 temp.depth = depth;
475 temp.CLASS = xclass;
476
477 default_depth = DefaultDepth(dpy,scr);
478 default_class = DefaultVisual(dpy,scr)->CLASS;
479
480 if (depth==default_depth && xclass==default_class) {
481 /* try to get root window's visual */
482 temp.visualid = DefaultVisual(dpy,scr)->visualid;
483 mask |= VisualIDMask;
484 }
485
486 vis = XGetVisualInfo( dpy, mask, &temp, &n );
487
488 /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
489 * An SGI Infinite Reality system, for example, can have 30bpp pixels:
490 * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel.
491 */
492 if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
493 if (bitcount(vis->red_mask) <= 8
494 && bitcount(vis->green_mask) <= 8
495 && bitcount(vis->blue_mask) <= 8) {
496 return vis;
497 }
498 else {
499 XFree((void *) vis);
500 return NULL;
501 }
502 }
503
504 return vis;
505 }
506
507
508
509 /*
510 * Retrieve the value of the given environment variable and find
511 * the X visual which matches it.
512 * Input: dpy - the display
513 * screen - the screen number
514 * varname - the name of the environment variable
515 * Return: an XVisualInfo pointer to NULL if error.
516 */
517 static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname)
518 {
519 char value[100], type[100];
520 int depth, xclass = -1;
521 XVisualInfo *vis;
522
523 if (!getenv( varname )) {
524 return NULL;
525 }
526
527 strncpy( value, getenv(varname), 100 );
528 value[99] = 0;
529
530 sscanf( value, "%s %d", type, &depth );
531
532 if (strcmp(type,"TrueColor")==0) xclass = TrueColor;
533 else if (strcmp(type,"DirectColor")==0) xclass = DirectColor;
534 else if (strcmp(type,"PseudoColor")==0) xclass = PseudoColor;
535 else if (strcmp(type,"StaticColor")==0) xclass = StaticColor;
536 else if (strcmp(type,"GrayScale")==0) xclass = GrayScale;
537 else if (strcmp(type,"StaticGray")==0) xclass = StaticGray;
538
539 if (xclass>-1 && depth>0) {
540 vis = get_visual( dpy, scr, depth, xclass );
541 if (vis) {
542 return vis;
543 }
544 }
545
546 fprintf( stderr, "Mesa: GLX unable to find visual class=%s, depth=%d.\n",
547 type, depth );
548 return NULL;
549 }
550
551
552
553 /*
554 * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
555 * Input: dpy, screen - X display and screen number
556 * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
557 * min_depth - minimum visual depth
558 * preferred_class - preferred GLX visual class or DONT_CARE
559 * Return: pointer to an XVisualInfo or NULL.
560 */
561 static XVisualInfo *choose_x_visual( Display *dpy, int screen,
562 GLboolean rgba, int min_depth,
563 int preferred_class )
564 {
565 XVisualInfo *vis;
566 int xclass, visclass;
567 int depth;
568
569 if (rgba) {
570 Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
571 /* First see if the MESA_RGB_VISUAL env var is defined */
572 vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
573 if (vis) {
574 return vis;
575 }
576 /* Otherwise, search for a suitable visual */
577 if (preferred_class==DONT_CARE) {
578 for (xclass=0;xclass<6;xclass++) {
579 switch (xclass) {
580 case 0: visclass = TrueColor; break;
581 case 1: visclass = DirectColor; break;
582 case 2: visclass = PseudoColor; break;
583 case 3: visclass = StaticColor; break;
584 case 4: visclass = GrayScale; break;
585 case 5: visclass = StaticGray; break;
586 }
587 if (min_depth==0) {
588 /* start with shallowest */
589 for (depth=0;depth<=32;depth++) {
590 if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
591 /* Special case: try to get 8-bit PseudoColor before */
592 /* 8-bit TrueColor */
593 vis = get_visual( dpy, screen, 8, PseudoColor );
594 if (vis) {
595 return vis;
596 }
597 }
598 vis = get_visual( dpy, screen, depth, visclass );
599 if (vis) {
600 return vis;
601 }
602 }
603 }
604 else {
605 /* start with deepest */
606 for (depth=32;depth>=min_depth;depth--) {
607 if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
608 /* Special case: try to get 8-bit PseudoColor before */
609 /* 8-bit TrueColor */
610 vis = get_visual( dpy, screen, 8, PseudoColor );
611 if (vis) {
612 return vis;
613 }
614 }
615 vis = get_visual( dpy, screen, depth, visclass );
616 if (vis) {
617 return vis;
618 }
619 }
620 }
621 }
622 }
623 else {
624 /* search for a specific visual class */
625 switch (preferred_class) {
626 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
627 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
628 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
629 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
630 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
631 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
632 default: return NULL;
633 }
634 if (min_depth==0) {
635 /* start with shallowest */
636 for (depth=0;depth<=32;depth++) {
637 vis = get_visual( dpy, screen, depth, visclass );
638 if (vis) {
639 return vis;
640 }
641 }
642 }
643 else {
644 /* start with deepest */
645 for (depth=32;depth>=min_depth;depth--) {
646 vis = get_visual( dpy, screen, depth, visclass );
647 if (vis) {
648 return vis;
649 }
650 }
651 }
652 }
653 }
654 else {
655 /* First see if the MESA_CI_VISUAL env var is defined */
656 vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
657 if (vis) {
658 return vis;
659 }
660 /* Otherwise, search for a suitable visual, starting with shallowest */
661 if (preferred_class==DONT_CARE) {
662 for (xclass=0;xclass<4;xclass++) {
663 switch (xclass) {
664 case 0: visclass = PseudoColor; break;
665 case 1: visclass = StaticColor; break;
666 case 2: visclass = GrayScale; break;
667 case 3: visclass = StaticGray; break;
668 }
669 /* try 8-bit up through 16-bit */
670 for (depth=8;depth<=16;depth++) {
671 vis = get_visual( dpy, screen, depth, visclass );
672 if (vis) {
673 return vis;
674 }
675 }
676 /* try min_depth up to 8-bit */
677 for (depth=min_depth;depth<8;depth++) {
678 vis = get_visual( dpy, screen, depth, visclass );
679 if (vis) {
680 return vis;
681 }
682 }
683 }
684 }
685 else {
686 /* search for a specific visual class */
687 switch (preferred_class) {
688 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
689 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
690 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
691 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
692 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
693 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
694 default: return NULL;
695 }
696 /* try 8-bit up through 16-bit */
697 for (depth=8;depth<=16;depth++) {
698 vis = get_visual( dpy, screen, depth, visclass );
699 if (vis) {
700 return vis;
701 }
702 }
703 /* try min_depth up to 8-bit */
704 for (depth=min_depth;depth<8;depth++) {
705 vis = get_visual( dpy, screen, depth, visclass );
706 if (vis) {
707 return vis;
708 }
709 }
710 }
711 }
712
713 /* didn't find a visual */
714 return NULL;
715 }
716
717
718
719 /*
720 * Find the deepest X over/underlay visual of at least min_depth.
721 * Input: dpy, screen - X display and screen number
722 * level - the over/underlay level
723 * trans_type - transparent pixel type: GLX_NONE_EXT,
724 * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
725 * or DONT_CARE
726 * trans_value - transparent pixel value or DONT_CARE
727 * min_depth - minimum visual depth
728 * preferred_class - preferred GLX visual class or DONT_CARE
729 * Return: pointer to an XVisualInfo or NULL.
730 */
731 static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr,
732 GLboolean rgbFlag,
733 int level, int trans_type,
734 int trans_value,
735 int min_depth,
736 int preferred_class )
737 {
738 Atom overlayVisualsAtom;
739 OverlayInfo *overlay_info;
740 int numOverlaysPerScreen;
741 Status status;
742 Atom actualType;
743 int actualFormat;
744 unsigned long sizeData, bytesLeft;
745 int i;
746 XVisualInfo *deepvis;
747 int deepest;
748
749 /*DEBUG int tt, tv; */
750
751 switch (preferred_class) {
752 case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break;
753 case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break;
754 case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break;
755 case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break;
756 case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break;
757 case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break;
758 default: preferred_class = DONT_CARE;
759 }
760
761 /*
762 * The SERVER_OVERLAY_VISUALS property on the root window contains
763 * a list of overlay visuals. Get that list now.
764 */
765 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
766 if (overlayVisualsAtom == (Atom) None) {
767 return NULL;
768 }
769
770 status = XGetWindowProperty(dpy, RootWindow( dpy, scr ),
771 overlayVisualsAtom, 0L, (long) 10000, False,
772 overlayVisualsAtom, &actualType, &actualFormat,
773 &sizeData, &bytesLeft,
774 (unsigned char **) &overlay_info );
775
776 if (status != Success || actualType != overlayVisualsAtom ||
777 actualFormat != 32 || sizeData < 4) {
778 /* something went wrong */
779 return NULL;
780 }
781
782 /* Search for the deepest overlay which satisifies all criteria. */
783 deepest = min_depth;
784 deepvis = NULL;
785
786 numOverlaysPerScreen = (int) (sizeData / 4);
787 for (i=0;i<numOverlaysPerScreen;i++) {
788 XVisualInfo *vislist, vistemplate;
789 int count;
790 OverlayInfo *ov;
791 ov = overlay_info + i;
792
793 if (ov->layer!=level) {
794 /* failed overlay level criteria */
795 continue;
796 }
797 if (!(trans_type==DONT_CARE
798 || (trans_type==GLX_TRANSPARENT_INDEX_EXT
799 && ov->transparent_type>0)
800 || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
801 /* failed transparent pixel type criteria */
802 continue;
803 }
804 if (trans_value!=DONT_CARE && trans_value!=ov->value) {
805 /* failed transparent pixel value criteria */
806 continue;
807 }
808
809 /* get XVisualInfo and check the depth */
810 vistemplate.visualid = ov->overlay_visual;
811 vistemplate.screen = scr;
812 vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
813 &vistemplate, &count );
814
815 if (count!=1) {
816 /* something went wrong */
817 continue;
818 }
819 if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
820 /* wrong visual class */
821 continue;
822 }
823
824 /* if RGB was requested, make sure we have True/DirectColor */
825 if (rgbFlag && vislist->CLASS != TrueColor
826 && vislist->CLASS != DirectColor)
827 continue;
828
829 /* if CI was requested, make sure we have a color indexed visual */
830 if (!rgbFlag
831 && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor))
832 continue;
833
834 if (deepvis==NULL || vislist->depth > deepest) {
835 /* YES! found a satisfactory visual */
836 if (deepvis) {
837 XFree( deepvis );
838 }
839 deepest = vislist->depth;
840 deepvis = vislist;
841 /* DEBUG tt = ov->transparent_type;*/
842 /* DEBUG tv = ov->value; */
843 }
844 }
845
846 /*DEBUG
847 if (deepvis) {
848 printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n",
849 deepvis->visualid, level, deepvis->depth, tt, tv );
850 }
851 */
852 return deepvis;
853 }
854
855
856
857 static XVisualInfo *
858 Fake_glXChooseVisual( Display *dpy, int screen, int *list )
859 {
860 int *parselist;
861 XVisualInfo *vis;
862 int min_ci = 0;
863 int min_red=0, min_green=0, min_blue=0;
864 GLboolean rgb_flag = GL_FALSE;
865 GLboolean alpha_flag = GL_FALSE;
866 GLboolean double_flag = GL_FALSE;
867 GLboolean stereo_flag = GL_FALSE;
868 GLint depth_size = 0;
869 GLint stencil_size = 0;
870 GLint accum_size = 0;
871 int level = 0;
872 int visual_type = DONT_CARE;
873 int trans_type = DONT_CARE;
874 int trans_value = DONT_CARE;
875
876 parselist = list;
877
878 while (*parselist) {
879
880 switch (*parselist) {
881 case GLX_USE_GL:
882 /* ignore */
883 parselist++;
884 break;
885 case GLX_BUFFER_SIZE:
886 parselist++;
887 min_ci = *parselist++;
888 break;
889 case GLX_LEVEL:
890 parselist++;
891 level = *parselist++;
892 break;
893 case GLX_RGBA:
894 rgb_flag = GL_TRUE;
895 parselist++;
896 break;
897 case GLX_DOUBLEBUFFER:
898 double_flag = GL_TRUE;
899 parselist++;
900 break;
901 case GLX_STEREO:
902 stereo_flag = GL_TRUE;
903 return NULL;
904 case GLX_AUX_BUFFERS:
905 /* ignore */
906 parselist++;
907 parselist++;
908 break;
909 case GLX_RED_SIZE:
910 parselist++;
911 min_red = *parselist++;
912 break;
913 case GLX_GREEN_SIZE:
914 parselist++;
915 min_green = *parselist++;
916 break;
917 case GLX_BLUE_SIZE:
918 parselist++;
919 min_blue = *parselist++;
920 break;
921 case GLX_ALPHA_SIZE:
922 parselist++;
923 {
924 GLint size = *parselist++;
925 alpha_flag = size>0 ? 1 : 0;
926 }
927 break;
928 case GLX_DEPTH_SIZE:
929 parselist++;
930 depth_size = *parselist++;
931 break;
932 case GLX_STENCIL_SIZE:
933 parselist++;
934 stencil_size = *parselist++;
935 break;
936 case GLX_ACCUM_RED_SIZE:
937 case GLX_ACCUM_GREEN_SIZE:
938 case GLX_ACCUM_BLUE_SIZE:
939 case GLX_ACCUM_ALPHA_SIZE:
940 parselist++;
941 {
942 GLint size = *parselist++;
943 accum_size = MAX2( accum_size, size );
944 }
945 break;
946
947 /*
948 * GLX_EXT_visual_info extension
949 */
950 case GLX_X_VISUAL_TYPE_EXT:
951 parselist++;
952 visual_type = *parselist++;
953 break;
954 case GLX_TRANSPARENT_TYPE_EXT:
955 parselist++;
956 trans_type = *parselist++;
957 break;
958 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
959 parselist++;
960 trans_value = *parselist++;
961 break;
962 case GLX_TRANSPARENT_RED_VALUE_EXT:
963 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
964 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
965 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
966 /* ignore */
967 parselist++;
968 parselist++;
969 break;
970
971 case None:
972 break;
973 default:
974 /* undefined attribute */
975 return NULL;
976 }
977 }
978
979 /*
980 * Since we're only simulating the GLX extension this function will never
981 * find any real GL visuals. Instead, all we can do is try to find an RGB
982 * or CI visual of appropriate depth. Other requested attributes such as
983 * double buffering, depth buffer, etc. will be associated with the X
984 * visual and stored in the VisualTable[].
985 */
986 if (level==0) {
987 /* normal color planes */
988 if (rgb_flag) {
989 /* Get an RGB visual */
990 int min_rgb = min_red + min_green + min_blue;
991 if (min_rgb>1 && min_rgb<8) {
992 /* a special case to be sure we can get a monochrome visual */
993 min_rgb = 1;
994 }
995 vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
996 }
997 else {
998 /* Get a color index visual */
999 vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
1000 accum_size = 0;
1001 }
1002 }
1003 else {
1004 /* over/underlay planes */
1005 if (rgb_flag) {
1006 /* rgba overlay */
1007 int min_rgb = min_red + min_green + min_blue;
1008 if (min_rgb>1 && min_rgb<8) {
1009 /* a special case to be sure we can get a monochrome visual */
1010 min_rgb = 1;
1011 }
1012 vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
1013 trans_type, trans_value, min_rgb, visual_type );
1014 }
1015 else {
1016 /* color index overlay */
1017 vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
1018 trans_type, trans_value, min_ci, visual_type );
1019 }
1020 }
1021
1022 if (vis) {
1023 /* Note: we're not exactly obeying the glXChooseVisual rules here.
1024 * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
1025 * largest depth buffer size, which is 32bits/value. However, we
1026 * return 16 to maintain performance with earlier versions of Mesa.
1027 */
1028 if (depth_size == 1)
1029 depth_size = DEFAULT_SOFTWARE_DEPTH_BITS;
1030 else if (depth_size > 24)
1031 depth_size = 31;
1032 else if (depth_size > 16)
1033 depth_size = 24;
1034 /* we only support one size of stencil and accum buffers. */
1035 if (stencil_size > 0)
1036 stencil_size = STENCIL_BITS;
1037 if (accum_size > 0)
1038 accum_size = ACCUM_BITS;
1039 if (!save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
1040 stereo_flag,
1041 depth_size, stencil_size, accum_size, level ))
1042 return NULL;
1043 }
1044
1045 return vis;
1046 }
1047
1048
1049
1050
1051 static GLXContext
1052 Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
1053 GLXContext share_list, Bool direct )
1054 {
1055 XMesaVisual glxvis;
1056 XMesaContext xmctx;
1057
1058 /* deallocate unused windows/buffers */
1059 XMesaGarbageCollect();
1060
1061 glxvis = find_glx_visual( dpy, visinfo );
1062 if (!glxvis) {
1063 /* This visual wasn't found with glXChooseVisual() */
1064 glxvis = create_glx_visual( dpy, visinfo );
1065 if (!glxvis) {
1066 /* unusable visual */
1067 return NULL;
1068 }
1069 }
1070
1071 xmctx = XMesaCreateContext( glxvis, (XMesaContext) share_list );
1072 if (xmctx) {
1073 /* set the direct/indirect flag */
1074 xmctx->direct = direct;
1075 }
1076 return (GLXContext) xmctx;
1077 }
1078
1079
1080 static GLXContext MakeCurrent_PrevContext = 0;
1081 static GLXDrawable MakeCurrent_PrevDrawable = 0;
1082 static GLXDrawable MakeCurrent_PrevReadable = 0;
1083 static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
1084 static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
1085
1086 /* GLX 1.3 and later */
1087 static Bool
1088 Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
1089 GLXDrawable read, GLXContext ctx )
1090 {
1091 if (ctx && draw && read) {
1092 XMesaBuffer drawBuffer, readBuffer;
1093 XMesaContext xmctx = (XMesaContext) ctx;
1094
1095 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
1096 if (ctx == MakeCurrent_PrevContext
1097 && draw == MakeCurrent_PrevDrawable) {
1098 drawBuffer = MakeCurrent_PrevDrawBuffer;
1099 }
1100 else {
1101 drawBuffer = XMesaFindBuffer( dpy, draw );
1102 }
1103 if (!drawBuffer) {
1104 /* drawable must be a new window! */
1105 drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, ctx );
1106 if (!drawBuffer) {
1107 /* Out of memory, or context/drawable depth mismatch */
1108 return False;
1109 }
1110 }
1111
1112 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
1113 if (ctx == MakeCurrent_PrevContext
1114 && read == MakeCurrent_PrevReadable) {
1115 readBuffer = MakeCurrent_PrevReadBuffer;
1116 }
1117 else {
1118 readBuffer = XMesaFindBuffer( dpy, read );
1119 }
1120 if (!readBuffer) {
1121 /* drawable must be a new window! */
1122 readBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, read, ctx );
1123 if (!readBuffer) {
1124 /* Out of memory, or context/drawable depth mismatch */
1125 return False;
1126 }
1127 }
1128
1129 MakeCurrent_PrevContext = ctx;
1130 MakeCurrent_PrevDrawable = draw;
1131 MakeCurrent_PrevReadable = read;
1132 MakeCurrent_PrevDrawBuffer = drawBuffer;
1133 MakeCurrent_PrevReadBuffer = readBuffer;
1134
1135 /* Now make current! */
1136 return (Bool) XMesaMakeCurrent2((XMesaContext) ctx, drawBuffer, readBuffer);
1137 }
1138 else if (!ctx && !draw && !read) {
1139 /* release current context w/out assigning new one. */
1140 XMesaMakeCurrent( NULL, NULL );
1141 MakeCurrent_PrevContext = 0;
1142 MakeCurrent_PrevDrawable = 0;
1143 MakeCurrent_PrevReadable = 0;
1144 MakeCurrent_PrevDrawBuffer = 0;
1145 MakeCurrent_PrevReadBuffer = 0;
1146 return True;
1147 }
1148 else {
1149 /* The args must either all be non-zero or all zero.
1150 * This is an error.
1151 */
1152 return False;
1153 }
1154 }
1155
1156
1157
1158 static Bool
1159 Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
1160 {
1161 return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx );
1162 }
1163
1164
1165
1166 static GLXPixmap
1167 Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
1168 {
1169 XMesaVisual v;
1170 XMesaBuffer b;
1171
1172 v = find_glx_visual( dpy, visinfo );
1173 if (!v) {
1174 v = create_glx_visual( dpy, visinfo );
1175 if (!v) {
1176 /* unusable visual */
1177 return 0;
1178 }
1179 }
1180
1181 b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
1182 if (!b) {
1183 return 0;
1184 }
1185 return b->frontbuffer;
1186 }
1187
1188
1189 #ifdef GLX_MESA_pixmap_colormap
1190
1191 static GLXPixmap
1192 Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
1193 Pixmap pixmap, Colormap cmap )
1194 {
1195 XMesaVisual v;
1196 XMesaBuffer b;
1197
1198 v = find_glx_visual( dpy, visinfo );
1199 if (!v) {
1200 v = create_glx_visual( dpy, visinfo );
1201 if (!v) {
1202 /* unusable visual */
1203 return 0;
1204 }
1205 }
1206
1207 b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
1208 if (!b) {
1209 return 0;
1210 }
1211 return b->frontbuffer;
1212 }
1213
1214 #endif
1215
1216
1217 static void
1218 Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
1219 {
1220 XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
1221 if (b) {
1222 XMesaDestroyBuffer(b);
1223 }
1224 else if (getenv("MESA_DEBUG")) {
1225 fprintf( stderr, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
1226 }
1227 }
1228
1229
1230 static void
1231 Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
1232 unsigned long mask )
1233 {
1234 XMesaContext xm_src = (XMesaContext) src;
1235 XMesaContext xm_dst = (XMesaContext) dst;
1236 (void) dpy;
1237 gl_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, (GLuint) mask );
1238 }
1239
1240
1241
1242 static Bool
1243 Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
1244 {
1245 /* Mesa's GLX isn't really an X extension but we try to act like one. */
1246 (void) dpy;
1247 (void) errorb;
1248 (void) event;
1249 return True;
1250 }
1251
1252
1253 extern void _kw_ungrab_all( Display *dpy );
1254 void _kw_ungrab_all( Display *dpy )
1255 {
1256 XUngrabPointer( dpy, CurrentTime );
1257 XUngrabKeyboard( dpy, CurrentTime );
1258 }
1259
1260
1261 static void
1262 Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
1263 {
1264 (void) dpy;
1265 MakeCurrent_PrevContext = 0;
1266 MakeCurrent_PrevDrawable = 0;
1267 MakeCurrent_PrevReadable = 0;
1268 MakeCurrent_PrevDrawBuffer = 0;
1269 MakeCurrent_PrevReadBuffer = 0;
1270 XMesaDestroyContext( (XMesaContext) ctx );
1271 XMesaGarbageCollect();
1272 }
1273
1274
1275
1276 static Bool
1277 Fake_glXIsDirect( Display *dpy, GLXContext ctx )
1278 {
1279 (void) dpy;
1280 return ((XMesaContext) ctx)->direct;
1281 }
1282
1283
1284
1285 static void
1286 Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
1287 {
1288 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1289
1290 if (buffer) {
1291 XMesaSwapBuffers(buffer);
1292 }
1293 else if (getenv("MESA_DEBUG")) {
1294 fprintf(stderr, "Mesa Warning: glXSwapBuffers: invalid drawable\n");
1295 }
1296 }
1297
1298
1299 static void
1300 Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
1301 int x, int y, int width, int height )
1302 {
1303 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1304 if (buffer) {
1305 XMesaCopySubBuffer(buffer, x, y, width, height);
1306 }
1307 else if (getenv("MESA_DEBUG")) {
1308 fprintf(stderr, "Mesa Warning: glXCopySubBufferMESA: invalid drawable\n");
1309 }
1310 }
1311
1312
1313
1314 static Bool
1315 Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
1316 {
1317 (void) dpy;
1318 /* Return GLX version, not Mesa version */
1319 assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
1320 *maj = CLIENT_MAJOR_VERSION;
1321 *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
1322 return True;
1323 }
1324
1325
1326
1327 /*
1328 * Query the GLX attributes of the given XVisualInfo.
1329 */
1330 static int
1331 Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
1332 int attrib, int *value )
1333 {
1334 XMesaVisual glxvis;
1335
1336 glxvis = find_glx_visual( dpy, visinfo );
1337 if (!glxvis) {
1338 /* this visual wasn't obtained with glXChooseVisual */
1339 glxvis = create_glx_visual( dpy, visinfo );
1340 if (!glxvis) {
1341 /* this visual can't be used for GL rendering */
1342 if (attrib==GLX_USE_GL) {
1343 *value = (int) False;
1344 return 0;
1345 }
1346 else {
1347 /*fprintf( stderr, "Mesa: Error in glXGetConfig: bad visual\n");*/
1348 return GLX_BAD_VISUAL;
1349 }
1350 }
1351 }
1352
1353 switch(attrib) {
1354 case GLX_USE_GL:
1355 *value = (int) True;
1356 return 0;
1357 case GLX_BUFFER_SIZE:
1358 *value = visinfo->depth;
1359 return 0;
1360 case GLX_LEVEL:
1361 *value = glxvis->level;
1362 return 0;
1363 case GLX_RGBA:
1364 if (glxvis->gl_visual->RGBAflag) {
1365 *value = True;
1366 }
1367 else {
1368 *value = False;
1369 }
1370 return 0;
1371 case GLX_DOUBLEBUFFER:
1372 *value = (int) glxvis->gl_visual->DBflag;
1373 return 0;
1374 case GLX_STEREO:
1375 *value = (int) glxvis->gl_visual->StereoFlag;
1376 return 0;
1377 case GLX_AUX_BUFFERS:
1378 *value = (int) False;
1379 return 0;
1380 case GLX_RED_SIZE:
1381 *value = glxvis->gl_visual->RedBits;
1382 return 0;
1383 case GLX_GREEN_SIZE:
1384 *value = glxvis->gl_visual->GreenBits;
1385 return 0;
1386 case GLX_BLUE_SIZE:
1387 *value = glxvis->gl_visual->BlueBits;
1388 return 0;
1389 case GLX_ALPHA_SIZE:
1390 *value = glxvis->gl_visual->AlphaBits;
1391 return 0;
1392 case GLX_DEPTH_SIZE:
1393 *value = glxvis->gl_visual->DepthBits;
1394 return 0;
1395 case GLX_STENCIL_SIZE:
1396 *value = glxvis->gl_visual->StencilBits;
1397 return 0;
1398 case GLX_ACCUM_RED_SIZE:
1399 case GLX_ACCUM_GREEN_SIZE:
1400 case GLX_ACCUM_BLUE_SIZE:
1401 *value = glxvis->gl_visual->AccumBits;
1402 return 0;
1403 case GLX_ACCUM_ALPHA_SIZE:
1404 if (glxvis->gl_visual->AlphaBits > 0)
1405 *value = glxvis->gl_visual->AccumBits;
1406 else
1407 *value = 0;
1408 return 0;
1409
1410 /*
1411 * GLX_EXT_visual_info extension
1412 */
1413 case GLX_X_VISUAL_TYPE_EXT:
1414 switch (glxvis->visinfo->CLASS) {
1415 case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0;
1416 case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0;
1417 case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0;
1418 case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0;
1419 case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0;
1420 case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0;
1421 }
1422 return 0;
1423 case GLX_TRANSPARENT_TYPE_EXT:
1424 if (glxvis->level==0) {
1425 /* normal planes */
1426 *value = GLX_NONE_EXT;
1427 }
1428 else if (glxvis->level>0) {
1429 /* overlay */
1430 if (glxvis->gl_visual->RGBAflag) {
1431 *value = GLX_TRANSPARENT_RGB_EXT;
1432 }
1433 else {
1434 *value = GLX_TRANSPARENT_INDEX_EXT;
1435 }
1436 }
1437 else if (glxvis->level<0) {
1438 /* underlay */
1439 *value = GLX_NONE_EXT;
1440 }
1441 return 0;
1442 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
1443 {
1444 int pixel = transparent_pixel( glxvis );
1445 if (pixel>=0) {
1446 *value = pixel;
1447 }
1448 /* else undefined */
1449 }
1450 return 0;
1451 case GLX_TRANSPARENT_RED_VALUE_EXT:
1452 /* undefined */
1453 return 0;
1454 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
1455 /* undefined */
1456 return 0;
1457 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
1458 /* undefined */
1459 return 0;
1460 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
1461 /* undefined */
1462 return 0;
1463
1464 /*
1465 * Extensions
1466 */
1467 default:
1468 return GLX_BAD_ATTRIBUTE;
1469 }
1470 }
1471
1472
1473
1474 static void
1475 Fake_glXWaitGL( void )
1476 {
1477 XMesaContext xmesa = XMesaGetCurrentContext();
1478 XMesaFlush( xmesa );
1479 }
1480
1481
1482
1483 static void
1484 Fake_glXWaitX( void )
1485 {
1486 XMesaContext xmesa = XMesaGetCurrentContext();
1487 XMesaFlush( xmesa );
1488 }
1489
1490
1491 /*
1492 * Return the extensions string, which is 3Dfx-dependant.
1493 */
1494 static const char *get_extensions( void )
1495 {
1496 #ifdef FX
1497 const char *fx = getenv("MESA_GLX_FX");
1498 if (fx && fx[0] != 'd') {
1499 return "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync GLX_MESA_set_3dfx_mode GLX_ARB_get_proc_address";
1500 }
1501 #endif
1502 return "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync GLX_ARB_get_proc_address";
1503 }
1504
1505
1506
1507 /* GLX 1.1 and later */
1508 static const char *
1509 Fake_glXQueryExtensionsString( Display *dpy, int screen )
1510 {
1511 (void) dpy;
1512 (void) screen;
1513 return get_extensions();
1514 }
1515
1516
1517
1518 /* GLX 1.1 and later */
1519 static const char *
1520 Fake_glXQueryServerString( Display *dpy, int screen, int name )
1521 {
1522 static char version[1000];
1523 sprintf(version, "%d.%d %s", SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION,
1524 MESA_GLX_VERSION);
1525
1526 (void) dpy;
1527 (void) screen;
1528
1529 switch (name) {
1530 case GLX_EXTENSIONS:
1531 return get_extensions();
1532 case GLX_VENDOR:
1533 return VENDOR;
1534 case GLX_VERSION:
1535 return version;
1536 default:
1537 return NULL;
1538 }
1539 }
1540
1541
1542
1543 /* GLX 1.1 and later */
1544 static const char *
1545 Fake_glXGetClientString( Display *dpy, int name )
1546 {
1547 static char version[1000];
1548 sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, CLIENT_MINOR_VERSION,
1549 MESA_GLX_VERSION);
1550
1551 (void) dpy;
1552
1553 switch (name) {
1554 case GLX_EXTENSIONS:
1555 return get_extensions();
1556 case GLX_VENDOR:
1557 return VENDOR;
1558 case GLX_VERSION:
1559 return version;
1560 default:
1561 return NULL;
1562 }
1563 }
1564
1565
1566
1567 /*
1568 * GLX 1.3 and later
1569 */
1570
1571 static GLXFBConfig
1572 Fake_glXChooseFBConfig( Display *dpy, int screen,
1573 const int *attribList, int *nitems )
1574 {
1575 (void) dpy;
1576 (void) screen;
1577 (void) attribList;
1578 (void) nitems;
1579 return 0;
1580 }
1581
1582
1583 static int
1584 Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
1585 int attribute, int *value )
1586 {
1587 (void) dpy;
1588 (void) config;
1589 (void) attribute;
1590 (void) value;
1591 return 0;
1592 }
1593
1594
1595 static XVisualInfo *
1596 Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
1597 {
1598 (void) dpy;
1599 (void) config;
1600 return 0;
1601 }
1602
1603
1604 static GLXWindow
1605 Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
1606 const int *attribList )
1607 {
1608 (void) dpy;
1609 (void) config;
1610 (void) win;
1611 (void) attribList;
1612 return 0;
1613 }
1614
1615
1616 static void
1617 Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
1618 {
1619 (void) dpy;
1620 (void) window;
1621 return;
1622 }
1623
1624
1625 static GLXPixmap
1626 Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
1627 const int *attribList )
1628 {
1629 (void) dpy;
1630 (void) config;
1631 (void) pixmap;
1632 (void) attribList;
1633 return 0;
1634 }
1635
1636
1637 static void
1638 Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
1639 {
1640 (void) dpy;
1641 (void) pixmap;
1642 return;
1643 }
1644
1645
1646 static GLXPbuffer
1647 Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
1648 const int *attribList )
1649 {
1650 (void) dpy;
1651 (void) config;
1652 (void) attribList;
1653 return 0;
1654 }
1655
1656
1657 static void
1658 Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
1659 {
1660 (void) dpy;
1661 (void) pbuf;
1662 }
1663
1664
1665 static void
1666 Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
1667 unsigned int *value )
1668 {
1669 (void) dpy;
1670 (void) draw;
1671 (void) attribute;
1672 (void) value;
1673 }
1674
1675
1676 static GLXContext
1677 Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
1678 int renderType, GLXContext shareList, Bool direct )
1679 {
1680 (void) dpy;
1681 (void) config;
1682 (void) renderType;
1683 (void) shareList;
1684 (void) direct;
1685 return 0;
1686 }
1687
1688
1689 static int
1690 Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
1691 {
1692 (void) dpy;
1693 (void) ctx;
1694 (void) attribute;
1695 (void) value;
1696 return 0;
1697 }
1698
1699
1700 static void
1701 Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
1702 {
1703 (void) dpy;
1704 (void) drawable;
1705 (void) mask;
1706 }
1707
1708
1709 static void
1710 Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
1711 unsigned long *mask )
1712 {
1713 (void) dpy;
1714 (void) drawable;
1715 (void) mask;
1716 }
1717
1718
1719
1720 /*
1721 * Release the depth, stencil, accum buffers attached to a GLXDrawable
1722 * (a window or pixmap) prior to destroying the GLXDrawable.
1723 */
1724 static Bool
1725 Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
1726 {
1727 XMesaBuffer b = XMesaFindBuffer(dpy, d);
1728 if (b) {
1729 XMesaDestroyBuffer(b);
1730 return True;
1731 }
1732 return False;
1733 }
1734
1735
1736 /*
1737 * GLX_MESA_set_3dfx_mode
1738 */
1739 static GLboolean
1740 Fake_glXSet3DfxModeMESA( GLint mode )
1741 {
1742 return XMesaSetFXmode( mode );
1743 }
1744
1745
1746 /*
1747 * GLX_SGI_video_sync
1748 */
1749
1750 #ifdef GLX_SGI_video_sync
1751
1752 static int
1753 Fake_glXGetVideoSyncSGI(unsigned int *count)
1754 {
1755 return 0;
1756 }
1757
1758
1759 static int
1760 Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
1761 {
1762 return 0;
1763 }
1764
1765 #endif
1766
1767
1768
1769 extern void Fake_glXUseXFont( Font font, int first, int count, int listbase );
1770
1771
1772 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
1773 struct _glxapi_table *_mesa_GetGLXDispatchTable(void)
1774 {
1775 static struct _glxapi_table glx;
1776
1777 /* be sure our dispatch table size <= libGL's table */
1778 {
1779 int size = sizeof(struct _glxapi_table) / sizeof(void *);
1780 (void) size;
1781 assert(_glxapi_get_dispatch_table_size() >= size);
1782 }
1783
1784 /* initialize the whole table to no-ops */
1785 _glxapi_set_no_op_table(&glx);
1786
1787 /* now initialize the table with the functions I implement */
1788 glx.ChooseVisual = Fake_glXChooseVisual;
1789 glx.CopyContext = Fake_glXCopyContext;
1790 glx.CreateContext = Fake_glXCreateContext;
1791 glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap;
1792 glx.DestroyContext = Fake_glXDestroyContext;
1793 glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap;
1794 glx.GetConfig = Fake_glXGetConfig;
1795 /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/
1796 /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/
1797 glx.IsDirect = Fake_glXIsDirect;
1798 glx.MakeCurrent = Fake_glXMakeCurrent;
1799 glx.QueryExtension = Fake_glXQueryExtension;
1800 glx.QueryVersion = Fake_glXQueryVersion;
1801 glx.SwapBuffers = Fake_glXSwapBuffers;
1802 glx.UseXFont = Fake_glXUseXFont;
1803 glx.WaitGL = Fake_glXWaitGL;
1804 glx.WaitX = Fake_glXWaitX;
1805
1806 #ifdef _GLXAPI_VERSION_1_1
1807 glx.GetClientString = Fake_glXGetClientString;
1808 glx.QueryExtensionsString = Fake_glXQueryExtensionsString;
1809 glx.QueryServerString = Fake_glXQueryServerString;
1810 #endif
1811
1812 #ifdef _GLXAPI_VERSION_1_2
1813 /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/
1814 #endif
1815
1816 #ifdef _GLXAPI_VERSION_1_3
1817 glx.ChooseFBConfig = Fake_glXChooseFBConfig;
1818 glx.CreateNewContext = Fake_glXCreateNewContext;
1819 glx.CreatePbuffer = Fake_glXCreatePbuffer;
1820 glx.CreatePixmap = Fake_glXCreatePixmap;
1821 glx.CreateWindow = Fake_glXCreateWindow;
1822 glx.DestroyPbuffer = Fake_glXDestroyPbuffer;
1823 glx.DestroyPixmap = Fake_glXDestroyPixmap;
1824 glx.DestroyWindow = Fake_glXDestroyWindow;
1825 /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/
1826 glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib;
1827 glx.GetSelectedEvent = Fake_glXGetSelectedEvent;
1828 glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig;
1829 glx.MakeContextCurrent = Fake_glXMakeContextCurrent;
1830 glx.QueryContext = Fake_glXQueryContext;
1831 glx.QueryDrawable = Fake_glXQueryDrawable;
1832 glx.SelectEvent = Fake_glXSelectEvent;
1833 #endif
1834
1835 #ifdef _GLXAPI_SGI_video_sync
1836 glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI;
1837 glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI;
1838 #endif
1839
1840 #ifdef _GLXAPI_MESA_copy_sub_buffer
1841 glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA;
1842 #endif
1843
1844 #ifdef _GLXAPI_MESA_release_buffers
1845 glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA;
1846 #endif
1847
1848 #ifdef _GLXAPI_MESA_pixmap_colormap
1849 glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA;
1850 #endif
1851
1852 #ifdef _GLXAPI_MESA_set_3dfx_mode
1853 glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA;
1854 #endif
1855
1856 return &glx;
1857 }