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