stub functions for glXAllocate/FreeMemoryNV()
[mesa.git] / src / mesa / drivers / x11 / fakeglx.c
1 /* $Id: fakeglx.c,v 1.67 2002/08/22 21:10:01 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 XVisualInfo *
901 Fake_glXChooseVisual( Display *dpy, int screen, int *list )
902 {
903 int *parselist;
904 XVisualInfo *vis;
905 int min_ci = 0;
906 int min_red=0, min_green=0, min_blue=0;
907 GLboolean rgb_flag = GL_FALSE;
908 GLboolean alpha_flag = GL_FALSE;
909 GLboolean double_flag = GL_FALSE;
910 GLboolean stereo_flag = GL_FALSE;
911 GLint depth_size = 0;
912 GLint stencil_size = 0;
913 GLint accumRedSize = 0;
914 GLint accumGreenSize = 0;
915 GLint accumBlueSize = 0;
916 GLint accumAlphaSize = 0;
917 int level = 0;
918 int visual_type = DONT_CARE;
919 int trans_type = DONT_CARE;
920 int trans_value = DONT_CARE;
921 GLint caveat = DONT_CARE;
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 case None:
1045 break;
1046 default:
1047 /* undefined attribute */
1048 return NULL;
1049 }
1050 }
1051
1052 /*
1053 * Since we're only simulating the GLX extension this function will never
1054 * find any real GL visuals. Instead, all we can do is try to find an RGB
1055 * or CI visual of appropriate depth. Other requested attributes such as
1056 * double buffering, depth buffer, etc. will be associated with the X
1057 * visual and stored in the VisualTable[].
1058 */
1059 if (level==0) {
1060 /* normal color planes */
1061 if (rgb_flag) {
1062 /* Get an RGB visual */
1063 int min_rgb = min_red + min_green + min_blue;
1064 if (min_rgb>1 && min_rgb<8) {
1065 /* a special case to be sure we can get a monochrome visual */
1066 min_rgb = 1;
1067 }
1068 vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
1069 }
1070 else {
1071 /* Get a color index visual */
1072 vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
1073 accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0;
1074 }
1075 }
1076 else {
1077 /* over/underlay planes */
1078 if (rgb_flag) {
1079 /* rgba overlay */
1080 int min_rgb = min_red + min_green + min_blue;
1081 if (min_rgb>1 && min_rgb<8) {
1082 /* a special case to be sure we can get a monochrome visual */
1083 min_rgb = 1;
1084 }
1085 vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
1086 trans_type, trans_value, min_rgb, visual_type );
1087 }
1088 else {
1089 /* color index overlay */
1090 vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
1091 trans_type, trans_value, min_ci, visual_type );
1092 }
1093 }
1094
1095 if (vis) {
1096 /* Note: we're not exactly obeying the glXChooseVisual rules here.
1097 * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
1098 * largest depth buffer size, which is 32bits/value. Instead, we
1099 * return 16 to maintain performance with earlier versions of Mesa.
1100 */
1101 if (depth_size > 24)
1102 depth_size = 31; /* 32 causes int overflow problems */
1103 else if (depth_size > 16)
1104 depth_size = 24;
1105 else if (depth_size > 0)
1106 depth_size = DEFAULT_SOFTWARE_DEPTH_BITS; /*16*/
1107
1108 /* we only support one size of stencil and accum buffers. */
1109 if (stencil_size > 0)
1110 stencil_size = STENCIL_BITS;
1111 if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 ||
1112 accumAlphaSize > 0) {
1113 accumRedSize = ACCUM_BITS;
1114 accumGreenSize = ACCUM_BITS;
1115 accumBlueSize = ACCUM_BITS;
1116 accumAlphaSize = alpha_flag ? ACCUM_BITS : 0;
1117 }
1118
1119 if (!save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
1120 stereo_flag, depth_size, stencil_size,
1121 accumRedSize, accumGreenSize,
1122 accumBlueSize, accumAlphaSize,
1123 level ))
1124 return NULL;
1125 }
1126
1127 return vis;
1128 }
1129
1130
1131
1132
1133 static GLXContext
1134 Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
1135 GLXContext share_list, Bool direct )
1136 {
1137 XMesaVisual glxvis;
1138 struct fake_glx_context *glxCtx;
1139 struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
1140
1141 if (!dpy || !visinfo)
1142 return 0;
1143
1144 glxCtx = CALLOC_STRUCT(fake_glx_context);
1145 if (!glxCtx)
1146 return 0;
1147
1148 /* deallocate unused windows/buffers */
1149 XMesaGarbageCollect();
1150
1151 glxvis = find_glx_visual( dpy, visinfo );
1152 if (!glxvis) {
1153 /* This visual wasn't found with glXChooseVisual() */
1154 glxvis = create_glx_visual( dpy, visinfo );
1155 if (!glxvis) {
1156 /* unusable visual */
1157 FREE(glxCtx);
1158 return NULL;
1159 }
1160 }
1161
1162 glxCtx->xmesaContext = XMesaCreateContext(glxvis,
1163 shareCtx ? shareCtx->xmesaContext : NULL);
1164 if (!glxCtx->xmesaContext) {
1165 FREE(glxCtx);
1166 return NULL;
1167 }
1168
1169 glxCtx->xmesaContext->direct = GL_FALSE;
1170 glxCtx->glxContext.isDirect = GL_FALSE;
1171 glxCtx->glxContext.currentDpy = dpy;
1172 glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
1173
1174 assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
1175
1176 return (GLXContext) glxCtx;
1177 }
1178
1179
1180 /* XXX these may have to be removed due to thread-safety issues. */
1181 static GLXContext MakeCurrent_PrevContext = 0;
1182 static GLXDrawable MakeCurrent_PrevDrawable = 0;
1183 static GLXDrawable MakeCurrent_PrevReadable = 0;
1184 static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
1185 static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
1186
1187
1188 /* GLX 1.3 and later */
1189 static Bool
1190 Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
1191 GLXDrawable read, GLXContext ctx )
1192 {
1193 struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
1194
1195 if (ctx && draw && read) {
1196 XMesaBuffer drawBuffer, readBuffer;
1197 XMesaContext xmctx = glxCtx->xmesaContext;
1198
1199 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
1200 if (ctx == MakeCurrent_PrevContext
1201 && draw == MakeCurrent_PrevDrawable) {
1202 drawBuffer = MakeCurrent_PrevDrawBuffer;
1203 }
1204 else {
1205 drawBuffer = XMesaFindBuffer( dpy, draw );
1206 }
1207 if (!drawBuffer) {
1208 /* drawable must be a new window! */
1209 drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, xmctx);
1210 if (!drawBuffer) {
1211 /* Out of memory, or context/drawable depth mismatch */
1212 return False;
1213 }
1214 }
1215
1216 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
1217 if (ctx == MakeCurrent_PrevContext
1218 && read == MakeCurrent_PrevReadable) {
1219 readBuffer = MakeCurrent_PrevReadBuffer;
1220 }
1221 else {
1222 readBuffer = XMesaFindBuffer( dpy, read );
1223 }
1224 if (!readBuffer) {
1225 /* drawable must be a new window! */
1226 readBuffer = XMesaCreateWindowBuffer2(glxCtx->xmesaContext->xm_visual,
1227 read, xmctx);
1228 if (!readBuffer) {
1229 /* Out of memory, or context/drawable depth mismatch */
1230 return False;
1231 }
1232 }
1233
1234 MakeCurrent_PrevContext = ctx;
1235 MakeCurrent_PrevDrawable = draw;
1236 MakeCurrent_PrevReadable = read;
1237 MakeCurrent_PrevDrawBuffer = drawBuffer;
1238 MakeCurrent_PrevReadBuffer = readBuffer;
1239
1240 /* Now make current! */
1241 if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
1242 ((__GLXcontext *) ctx)->currentDpy = dpy;
1243 ((__GLXcontext *) ctx)->currentDrawable = draw;
1244 #ifndef GLX_BUILT_IN_XMESA
1245 ((__GLXcontext *) ctx)->currentReadable = read;
1246 #else
1247 __glXSetCurrentContext(ctx);
1248 #endif
1249 return True;
1250 }
1251 else {
1252 return False;
1253 }
1254 }
1255 else if (!ctx && !draw && !read) {
1256 /* release current context w/out assigning new one. */
1257 XMesaMakeCurrent( NULL, NULL );
1258 MakeCurrent_PrevContext = 0;
1259 MakeCurrent_PrevDrawable = 0;
1260 MakeCurrent_PrevReadable = 0;
1261 MakeCurrent_PrevDrawBuffer = 0;
1262 MakeCurrent_PrevReadBuffer = 0;
1263 #ifdef GLX_BUILT_IN_XMESA
1264 /* XXX bind dummy context with __glXSetCurrentContext(ctx); */
1265 #endif
1266 return True;
1267 }
1268 else {
1269 /* The args must either all be non-zero or all zero.
1270 * This is an error.
1271 */
1272 return False;
1273 }
1274 }
1275
1276
1277
1278 static Bool
1279 Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
1280 {
1281 return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx );
1282 }
1283
1284
1285
1286 static GLXPixmap
1287 Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
1288 {
1289 XMesaVisual v;
1290 XMesaBuffer b;
1291
1292 v = find_glx_visual( dpy, visinfo );
1293 if (!v) {
1294 v = create_glx_visual( dpy, visinfo );
1295 if (!v) {
1296 /* unusable visual */
1297 return 0;
1298 }
1299 }
1300
1301 b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
1302 if (!b) {
1303 return 0;
1304 }
1305 return b->frontbuffer;
1306 }
1307
1308
1309 /*** GLX_MESA_pixmap_colormap ***/
1310
1311 static GLXPixmap
1312 Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
1313 Pixmap pixmap, Colormap cmap )
1314 {
1315 XMesaVisual v;
1316 XMesaBuffer b;
1317
1318 v = find_glx_visual( dpy, visinfo );
1319 if (!v) {
1320 v = create_glx_visual( dpy, visinfo );
1321 if (!v) {
1322 /* unusable visual */
1323 return 0;
1324 }
1325 }
1326
1327 b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
1328 if (!b) {
1329 return 0;
1330 }
1331 return b->frontbuffer;
1332 }
1333
1334
1335 static void
1336 Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
1337 {
1338 XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
1339 if (b) {
1340 XMesaDestroyBuffer(b);
1341 }
1342 else if (getenv("MESA_DEBUG")) {
1343 _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
1344 }
1345 }
1346
1347
1348
1349 static void
1350 Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
1351 unsigned long mask )
1352 {
1353 struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src;
1354 struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst;
1355 XMesaContext xm_src = fakeSrc->xmesaContext;
1356 XMesaContext xm_dst = fakeDst->xmesaContext;
1357 (void) dpy;
1358 _mesa_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, (GLuint) mask );
1359 }
1360
1361
1362
1363 static Bool
1364 Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
1365 {
1366 /* Mesa's GLX isn't really an X extension but we try to act like one. */
1367 (void) dpy;
1368 (void) errorb;
1369 (void) event;
1370 return True;
1371 }
1372
1373
1374 extern void _kw_ungrab_all( Display *dpy );
1375 void _kw_ungrab_all( Display *dpy )
1376 {
1377 XUngrabPointer( dpy, CurrentTime );
1378 XUngrabKeyboard( dpy, CurrentTime );
1379 }
1380
1381
1382 static void
1383 Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
1384 {
1385 struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
1386 (void) dpy;
1387 MakeCurrent_PrevContext = 0;
1388 MakeCurrent_PrevDrawable = 0;
1389 MakeCurrent_PrevReadable = 0;
1390 MakeCurrent_PrevDrawBuffer = 0;
1391 MakeCurrent_PrevReadBuffer = 0;
1392 XMesaDestroyContext( glxCtx->xmesaContext );
1393 XMesaGarbageCollect();
1394 }
1395
1396
1397
1398 static Bool
1399 Fake_glXIsDirect( Display *dpy, GLXContext ctx )
1400 {
1401 struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
1402 (void) dpy;
1403 return glxCtx->xmesaContext->direct;
1404 }
1405
1406
1407
1408 static void
1409 Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
1410 {
1411 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1412
1413 if (buffer) {
1414 XMesaSwapBuffers(buffer);
1415 }
1416 else if (getenv("MESA_DEBUG")) {
1417 _mesa_warning(NULL, "Mesa: glXSwapBuffers: invalid drawable\n");
1418 }
1419 }
1420
1421
1422
1423 /*** GLX_MESA_copy_sub_buffer ***/
1424
1425 static void
1426 Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
1427 int x, int y, int width, int height )
1428 {
1429 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
1430 if (buffer) {
1431 XMesaCopySubBuffer(buffer, x, y, width, height);
1432 }
1433 else if (getenv("MESA_DEBUG")) {
1434 _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n");
1435 }
1436 }
1437
1438
1439
1440 static Bool
1441 Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
1442 {
1443 (void) dpy;
1444 /* Return GLX version, not Mesa version */
1445 assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
1446 *maj = CLIENT_MAJOR_VERSION;
1447 *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
1448 return True;
1449 }
1450
1451
1452
1453 /*
1454 * Query the GLX attributes of the given XVisualInfo.
1455 */
1456 static int
1457 Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
1458 int attrib, int *value )
1459 {
1460 XMesaVisual glxvis;
1461
1462 glxvis = find_glx_visual( dpy, visinfo );
1463 if (!glxvis) {
1464 /* this visual wasn't obtained with glXChooseVisual */
1465 glxvis = create_glx_visual( dpy, visinfo );
1466 if (!glxvis) {
1467 /* this visual can't be used for GL rendering */
1468 if (attrib==GLX_USE_GL) {
1469 *value = (int) False;
1470 return 0;
1471 }
1472 else {
1473 return GLX_BAD_VISUAL;
1474 }
1475 }
1476 }
1477
1478 switch(attrib) {
1479 case GLX_USE_GL:
1480 *value = (int) True;
1481 return 0;
1482 case GLX_BUFFER_SIZE:
1483 *value = visinfo->depth;
1484 return 0;
1485 case GLX_LEVEL:
1486 *value = glxvis->level;
1487 return 0;
1488 case GLX_RGBA:
1489 if (glxvis->mesa_visual.rgbMode) {
1490 *value = True;
1491 }
1492 else {
1493 *value = False;
1494 }
1495 return 0;
1496 case GLX_DOUBLEBUFFER:
1497 *value = (int) glxvis->mesa_visual.doubleBufferMode;
1498 return 0;
1499 case GLX_STEREO:
1500 *value = (int) glxvis->mesa_visual.stereoMode;
1501 return 0;
1502 case GLX_AUX_BUFFERS:
1503 *value = (int) False;
1504 return 0;
1505 case GLX_RED_SIZE:
1506 *value = glxvis->mesa_visual.redBits;
1507 return 0;
1508 case GLX_GREEN_SIZE:
1509 *value = glxvis->mesa_visual.greenBits;
1510 return 0;
1511 case GLX_BLUE_SIZE:
1512 *value = glxvis->mesa_visual.blueBits;
1513 return 0;
1514 case GLX_ALPHA_SIZE:
1515 *value = glxvis->mesa_visual.alphaBits;
1516 return 0;
1517 case GLX_DEPTH_SIZE:
1518 *value = glxvis->mesa_visual.depthBits;
1519 return 0;
1520 case GLX_STENCIL_SIZE:
1521 *value = glxvis->mesa_visual.stencilBits;
1522 return 0;
1523 case GLX_ACCUM_RED_SIZE:
1524 *value = glxvis->mesa_visual.accumRedBits;
1525 return 0;
1526 case GLX_ACCUM_GREEN_SIZE:
1527 *value = glxvis->mesa_visual.accumGreenBits;
1528 return 0;
1529 case GLX_ACCUM_BLUE_SIZE:
1530 *value = glxvis->mesa_visual.accumBlueBits;
1531 return 0;
1532 case GLX_ACCUM_ALPHA_SIZE:
1533 *value = glxvis->mesa_visual.accumAlphaBits;
1534 return 0;
1535
1536 /*
1537 * GLX_EXT_visual_info extension
1538 */
1539 case GLX_X_VISUAL_TYPE_EXT:
1540 switch (glxvis->visinfo->CLASS) {
1541 case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0;
1542 case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0;
1543 case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0;
1544 case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0;
1545 case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0;
1546 case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0;
1547 }
1548 return 0;
1549 case GLX_TRANSPARENT_TYPE_EXT:
1550 if (glxvis->level==0) {
1551 /* normal planes */
1552 *value = GLX_NONE_EXT;
1553 }
1554 else if (glxvis->level>0) {
1555 /* overlay */
1556 if (glxvis->mesa_visual.rgbMode) {
1557 *value = GLX_TRANSPARENT_RGB_EXT;
1558 }
1559 else {
1560 *value = GLX_TRANSPARENT_INDEX_EXT;
1561 }
1562 }
1563 else if (glxvis->level<0) {
1564 /* underlay */
1565 *value = GLX_NONE_EXT;
1566 }
1567 return 0;
1568 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
1569 {
1570 int pixel = transparent_pixel( glxvis );
1571 if (pixel>=0) {
1572 *value = pixel;
1573 }
1574 /* else undefined */
1575 }
1576 return 0;
1577 case GLX_TRANSPARENT_RED_VALUE_EXT:
1578 /* undefined */
1579 return 0;
1580 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
1581 /* undefined */
1582 return 0;
1583 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
1584 /* undefined */
1585 return 0;
1586 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
1587 /* undefined */
1588 return 0;
1589
1590 /*
1591 * GLX_EXT_visual_info extension
1592 */
1593 case GLX_VISUAL_CAVEAT_EXT:
1594 /* test for zero, just in case */
1595 if (glxvis->VisualCaveat > 0)
1596 *value = glxvis->VisualCaveat;
1597 else
1598 *value = GLX_NONE_EXT;
1599 return 0;
1600
1601 /*
1602 * Extensions
1603 */
1604 default:
1605 return GLX_BAD_ATTRIBUTE;
1606 }
1607 }
1608
1609
1610
1611 static void
1612 Fake_glXWaitGL( void )
1613 {
1614 XMesaContext xmesa = XMesaGetCurrentContext();
1615 XMesaFlush( xmesa );
1616 }
1617
1618
1619
1620 static void
1621 Fake_glXWaitX( void )
1622 {
1623 XMesaContext xmesa = XMesaGetCurrentContext();
1624 XMesaFlush( xmesa );
1625 }
1626
1627
1628 /*
1629 * Return the extensions string, which is 3Dfx-dependant.
1630 */
1631 static const char *get_extensions( void )
1632 {
1633 #ifdef FX
1634 const char *fx = getenv("MESA_GLX_FX");
1635 if (fx && fx[0] != 'd') {
1636 return "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_EXT_visual_rating GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync GLX_MESA_set_3dfx_mode GLX_ARB_get_proc_address";
1637 }
1638 #endif
1639 return "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_EXT_visual_rating GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync GLX_ARB_get_proc_address";
1640 }
1641
1642
1643
1644 /* GLX 1.1 and later */
1645 static const char *
1646 Fake_glXQueryExtensionsString( Display *dpy, int screen )
1647 {
1648 (void) dpy;
1649 (void) screen;
1650 return get_extensions();
1651 }
1652
1653
1654
1655 /* GLX 1.1 and later */
1656 static const char *
1657 Fake_glXQueryServerString( Display *dpy, int screen, int name )
1658 {
1659 static char version[1000];
1660 sprintf(version, "%d.%d %s", SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION,
1661 MESA_GLX_VERSION);
1662
1663 (void) dpy;
1664 (void) screen;
1665
1666 switch (name) {
1667 case GLX_EXTENSIONS:
1668 return get_extensions();
1669 case GLX_VENDOR:
1670 return VENDOR;
1671 case GLX_VERSION:
1672 return version;
1673 default:
1674 return NULL;
1675 }
1676 }
1677
1678
1679
1680 /* GLX 1.1 and later */
1681 static const char *
1682 Fake_glXGetClientString( Display *dpy, int name )
1683 {
1684 static char version[1000];
1685 sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, CLIENT_MINOR_VERSION,
1686 MESA_GLX_VERSION);
1687
1688 (void) dpy;
1689
1690 switch (name) {
1691 case GLX_EXTENSIONS:
1692 return get_extensions();
1693 case GLX_VENDOR:
1694 return VENDOR;
1695 case GLX_VERSION:
1696 return version;
1697 default:
1698 return NULL;
1699 }
1700 }
1701
1702
1703
1704 /*
1705 * GLX 1.3 and later
1706 */
1707
1708 /* XXX Move this when done.
1709 * Create an XMesaBuffer as a Pbuffer.
1710 * New in Mesa 4.0 but untested.
1711 */
1712 extern XMesaBuffer XMesaCreatePBuffer( XMesaVisual v, XMesaColormap cmap,
1713 unsigned int width, unsigned int height );
1714
1715
1716
1717 /* PBUFFER */
1718 static GLXFBConfig *
1719 Fake_glXChooseFBConfig( Display *dpy, int screen,
1720 const int *attribList, int *nitems )
1721 {
1722 (void) dpy;
1723 (void) screen;
1724 (void) attribList;
1725 (void) nitems;
1726 return 0;
1727 }
1728
1729
1730 /* PBUFFER */
1731 static int
1732 Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
1733 int attribute, int *value )
1734 {
1735 XMesaVisual v = NULL; /* XXX Fix this */
1736 (void) dpy;
1737 (void) config;
1738 (void) attribute;
1739 (void) value;
1740
1741 if (!dpy || !config || !value)
1742 return -1;
1743
1744 switch (attribute) {
1745 case GLX_FBCONFIG_ID:
1746 case GLX_BUFFER_SIZE:
1747 if (v->mesa_visual.rgbMode)
1748 *value = v->mesa_visual.redBits + v->mesa_visual.greenBits +
1749 v->mesa_visual.blueBits + v->mesa_visual.alphaBits;
1750 else
1751 *value = v->mesa_visual.indexBits;
1752 break;
1753 case GLX_LEVEL:
1754 *value = v->level;
1755 break;
1756 case GLX_DOUBLEBUFFER:
1757 *value = v->mesa_visual.doubleBufferMode;
1758 break;
1759 case GLX_STEREO:
1760 *value = v->mesa_visual.stereoMode;
1761 break;
1762 case GLX_AUX_BUFFERS:
1763 *value = v->mesa_visual.numAuxBuffers;
1764 break;
1765 case GLX_RED_SIZE:
1766 *value = v->mesa_visual.redBits;
1767 break;
1768 case GLX_GREEN_SIZE:
1769 *value = v->mesa_visual.greenBits;
1770 break;
1771 case GLX_BLUE_SIZE:
1772 *value = v->mesa_visual.blueBits;
1773 break;
1774 case GLX_ALPHA_SIZE:
1775 *value = v->mesa_visual.alphaBits;
1776 break;
1777 case GLX_DEPTH_SIZE:
1778 *value = v->mesa_visual.depthBits;
1779 break;
1780 case GLX_STENCIL_SIZE:
1781 *value = v->mesa_visual.stencilBits;
1782 break;
1783 case GLX_ACCUM_RED_SIZE:
1784 *value = v->mesa_visual.accumRedBits;
1785 break;
1786 case GLX_ACCUM_GREEN_SIZE:
1787 *value = v->mesa_visual.accumGreenBits;
1788 break;
1789 case GLX_ACCUM_BLUE_SIZE:
1790 *value = v->mesa_visual.accumBlueBits;
1791 break;
1792 case GLX_ACCUM_ALPHA_SIZE:
1793 *value = v->mesa_visual.accumAlphaBits;
1794 break;
1795 case GLX_RENDER_TYPE:
1796 *value = 0; /* XXX ??? */
1797 break;
1798 case GLX_DRAWABLE_TYPE:
1799 *value = GLX_PBUFFER_BIT; /* XXX fix? */
1800 break;
1801 case GLX_X_RENDERABLE:
1802 *value = False; /* XXX ??? */
1803 break;
1804 case GLX_X_VISUAL_TYPE:
1805 #if defined(__cplusplus) || defined(c_plusplus)
1806 switch (v->vishandle->c_class) {
1807 #else
1808 switch (v->vishandle->class) {
1809 #endif
1810 case GrayScale:
1811 *value = GLX_GRAY_SCALE;
1812 break;
1813 case StaticGray:
1814 *value = GLX_STATIC_GRAY;
1815 break;
1816 case StaticColor:
1817 *value = GLX_STATIC_COLOR;
1818 break;
1819 case PseudoColor:
1820 *value = GLX_PSEUDO_COLOR;
1821 break;
1822 case TrueColor:
1823 *value = GLX_TRUE_COLOR;
1824 break;
1825 case DirectColor:
1826 *value = GLX_DIRECT_COLOR;
1827 break;
1828 default:
1829 *value = 0;
1830 }
1831 break;
1832 case GLX_CONFIG_CAVEAT:
1833 *value = 0; /* XXX ??? */
1834 break;
1835 case GLX_TRANSPARENT_TYPE:
1836 if (v->level == 0) {
1837 /* normal planes */
1838 *value = GLX_NONE_EXT;
1839 }
1840 else if (v->level > 0) {
1841 /* overlay */
1842 if (v->mesa_visual.rgbMode) {
1843 *value = GLX_TRANSPARENT_RGB_EXT;
1844 }
1845 else {
1846 *value = GLX_TRANSPARENT_INDEX_EXT;
1847 }
1848 }
1849 else if (v->level < 0) {
1850 /* underlay */
1851 *value = GLX_NONE_EXT;
1852 }
1853 break;
1854 case GLX_TRANSPARENT_INDEX_VALUE:
1855 *value = transparent_pixel( v );
1856 break;
1857 case GLX_TRANSPARENT_RED_VALUE:
1858 *value = 0; /* not implemented */
1859 break;
1860 case GLX_TRANSPARENT_GREEN_VALUE:
1861 *value = 0; /* not implemented */
1862 break;
1863 case GLX_TRANSPARENT_BLUE_VALUE:
1864 *value = 0; /* not implemented */
1865 break;
1866 case GLX_TRANSPARENT_ALPHA_VALUE:
1867 *value = 0; /* not implemented */
1868 break;
1869 case GLX_MAX_PBUFFER_WIDTH:
1870 *value = DisplayWidth(dpy, v->vishandle->screen);
1871 break;
1872 case GLX_MAX_PBUFFER_HEIGHT:
1873 *value = DisplayHeight(dpy, v->vishandle->screen);
1874 break;
1875 case GLX_MAX_PBUFFER_PIXELS:
1876 *value = DisplayWidth(dpy, v->vishandle->screen) *
1877 DisplayHeight(dpy, v->vishandle->screen);
1878 break;
1879 case GLX_VISUAL_ID:
1880 *value = v->vishandle->visualid;
1881 break;
1882 default:
1883 return GLX_BAD_ATTRIBUTE;
1884 }
1885
1886 return Success;
1887 }
1888
1889
1890 /* PBUFFER */
1891 static GLXFBConfig *
1892 Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
1893 {
1894 /* Get list of all X visuals, create FBconfigs from them */
1895 (void) dpy;
1896 (void) screen;
1897 nelements = 0;
1898 return 0;
1899 }
1900
1901
1902 /* PBUFFER */
1903 static XVisualInfo *
1904 Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
1905 {
1906 if (dpy && config) {
1907 XMesaVisual v = (XMesaVisual) config;
1908 return v->vishandle;
1909 }
1910 else {
1911 return NULL;
1912 }
1913 }
1914
1915
1916 /* PBUFFER */
1917 static GLXWindow
1918 Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
1919 const int *attribList )
1920 {
1921 (void) dpy;
1922 (void) config;
1923 (void) win;
1924 (void) attribList; /* Ignored in GLX 1.3 */
1925
1926 return win; /* A hack for now */
1927 }
1928
1929
1930 static void
1931 Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
1932 {
1933 XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window);
1934 if (b)
1935 XMesaDestroyBuffer(b);
1936 /* don't destroy X window */
1937 }
1938
1939
1940 /* XXX untested */
1941 static GLXPixmap
1942 Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
1943 const int *attribList )
1944 {
1945 XMesaVisual v = (XMesaVisual) config;
1946 XVisualInfo *visinfo;
1947 XMesaBuffer b;
1948
1949 (void) dpy;
1950 (void) config;
1951 (void) pixmap;
1952 (void) attribList; /* Ignored in GLX 1.3 */
1953
1954 if (!dpy || !config || !pixmap)
1955 return 0;
1956
1957 visinfo = v->vishandle;
1958
1959 v = find_glx_visual( dpy, visinfo );
1960 if (!v) {
1961 v = create_glx_visual( dpy, visinfo );
1962 if (!v) {
1963 /* unusable visual */
1964 return 0;
1965 }
1966 }
1967
1968 b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
1969 if (!b) {
1970 return 0;
1971 }
1972
1973 return pixmap;
1974 }
1975
1976
1977 static void
1978 Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
1979 {
1980 XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap);
1981 if (b)
1982 XMesaDestroyBuffer(b);
1983 /* don't destroy X pixmap */
1984 }
1985
1986
1987 /* PBUFFER */
1988 static GLXPbuffer
1989 Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
1990 const int *attribList )
1991 {
1992 const int *attrib;
1993 int width = 0, height = 0;
1994 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
1995
1996 (void) dpy;
1997 (void) config;
1998
1999 for (attrib = attribList; attrib; attrib++) {
2000 switch (*attrib) {
2001 case GLX_PBUFFER_WIDTH:
2002 width = *(++attrib);
2003 break;
2004 case GLX_PBUFFER_HEIGHT:
2005 height = *(++attrib);
2006 break;
2007 case GLX_PRESERVED_CONTENTS:
2008 preserveContents = GL_TRUE; /* ignored */
2009 break;
2010 case GLX_LARGEST_PBUFFER:
2011 useLargest = GL_TRUE; /* ignored */
2012 break;
2013 default:
2014 return 0;
2015 }
2016 }
2017
2018 if (width == 0 || height == 0)
2019 return 0;
2020
2021
2022 return 0;
2023 }
2024
2025
2026 /* PBUFFER */
2027 static void
2028 Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
2029 {
2030 (void) dpy;
2031 (void) pbuf;
2032 }
2033
2034
2035 /* PBUFFER */
2036 static void
2037 Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
2038 unsigned int *value )
2039 {
2040 (void) dpy;
2041 (void) draw;
2042
2043 switch (attribute) {
2044 case GLX_WIDTH:
2045 case GLX_HEIGHT:
2046 case GLX_PRESERVED_CONTENTS:
2047 case GLX_LARGEST_PBUFFER:
2048 case GLX_FBCONFIG_ID:
2049 *value = 0;
2050 return;
2051 default:
2052 return; /* GLX_BAD_ATTRIBUTE? */
2053 }
2054 }
2055
2056
2057 static GLXContext
2058 Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
2059 int renderType, GLXContext shareList, Bool direct )
2060 {
2061 XMesaVisual v = (XMesaVisual) config;
2062
2063 if (!dpy || !config ||
2064 (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
2065 return 0;
2066
2067 return Fake_glXCreateContext(dpy, v->vishandle, shareList, direct);
2068 }
2069
2070
2071 /* PBUFFER */
2072 static int
2073 Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
2074 {
2075 (void) dpy;
2076 (void) ctx;
2077
2078 switch (attribute) {
2079 case GLX_FBCONFIG_ID:
2080 case GLX_RENDER_TYPE:
2081 case GLX_SCREEN:
2082 *value = 0;
2083 return Success;
2084 default:
2085 return GLX_BAD_ATTRIBUTE;
2086 }
2087 }
2088
2089
2090 /* PBUFFER */
2091 static void
2092 Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
2093 {
2094 (void) dpy;
2095 (void) drawable;
2096 (void) mask;
2097 }
2098
2099
2100 /* PBUFFER */
2101 static void
2102 Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
2103 unsigned long *mask )
2104 {
2105 (void) dpy;
2106 (void) drawable;
2107 (void) mask;
2108 }
2109
2110
2111
2112 /*** GLX_SGI_swap_control ***/
2113
2114 static int
2115 Fake_glXSwapIntervalSGI(int interval)
2116 {
2117 (void) interval;
2118 return 0;
2119 }
2120
2121
2122
2123 /*** GLX_SGI_video_sync ***/
2124
2125 static int
2126 Fake_glXGetVideoSyncSGI(unsigned int *count)
2127 {
2128 (void) count;
2129 return 0;
2130 }
2131
2132 static int
2133 Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
2134 {
2135 (void) divisor;
2136 (void) remainder;
2137 (void) count;
2138 return 0;
2139 }
2140
2141
2142
2143 /*** GLX_SGI_make_current_read ***/
2144
2145 static Bool
2146 Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
2147 {
2148 return Fake_glXMakeContextCurrent( dpy, draw, read, ctx );
2149 }
2150
2151 /* not used
2152 static GLXDrawable
2153 Fake_glXGetCurrentReadDrawableSGI(void)
2154 {
2155 return 0;
2156 }
2157 */
2158
2159
2160 /*** GLX_SGIX_video_source ***/
2161 #if defined(_VL_H)
2162
2163 static GLXVideoSourceSGIX
2164 Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
2165 {
2166 (void) dpy;
2167 (void) screen;
2168 (void) server;
2169 (void) path;
2170 (void) nodeClass;
2171 (void) drainNode;
2172 return 0;
2173 }
2174
2175 static void
2176 Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
2177 {
2178 (void) dpy;
2179 (void) src;
2180 }
2181
2182 #endif
2183
2184
2185 /*** GLX_EXT_import_context ***/
2186
2187 static void
2188 Fake_glXFreeContextEXT(Display *dpy, GLXContext context)
2189 {
2190 (void) dpy;
2191 (void) context;
2192 }
2193
2194 static GLXContextID
2195 Fake_glXGetContextIDEXT(const GLXContext context)
2196 {
2197 (void) context;
2198 return 0;
2199 }
2200
2201 static GLXContext
2202 Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID)
2203 {
2204 (void) dpy;
2205 (void) contextID;
2206 return 0;
2207 }
2208
2209 static int
2210 Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
2211 {
2212 (void) dpy;
2213 (void) context;
2214 (void) attribute;
2215 (void) value;
2216 return 0;
2217 }
2218
2219
2220
2221 /*** GLX_SGIX_fbconfig ***/
2222
2223 static int
2224 Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
2225 {
2226 (void) dpy;
2227 (void) config;
2228 (void) attribute;
2229 (void) value;
2230 return 0;
2231 }
2232
2233 static GLXFBConfigSGIX *
2234 Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
2235 {
2236 (void) dpy;
2237 (void) screen;
2238 (void) attrib_list;
2239 (void) nelements;
2240 return 0;
2241 }
2242
2243 static GLXPixmap
2244 Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
2245 {
2246 (void) dpy;
2247 (void) config;
2248 (void) pixmap;
2249 return 0;
2250 }
2251
2252 static GLXContext
2253 Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
2254 {
2255 (void) dpy;
2256 (void) config;
2257 (void) render_type;
2258 (void) share_list;
2259 (void) direct;
2260 return 0;
2261 }
2262
2263 static XVisualInfo *
2264 Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
2265 {
2266 (void) dpy;
2267 (void) config;
2268 return NULL;
2269 }
2270
2271 static GLXFBConfigSGIX
2272 Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
2273 {
2274 (void) dpy;
2275 (void) vis;
2276 return 0;
2277 }
2278
2279
2280
2281 /*** GLX_SGIX_pbuffer ***/
2282
2283 static GLXPbufferSGIX
2284 Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
2285 {
2286 (void) dpy;
2287 (void) config;
2288 (void) width;
2289 (void) height;
2290 (void) attrib_list;
2291 return 0;
2292 }
2293
2294 static void
2295 Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
2296 {
2297 (void) dpy;
2298 (void) pbuf;
2299 }
2300
2301 static int
2302 Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
2303 {
2304 (void) dpy;
2305 (void) pbuf;
2306 (void) attribute;
2307 (void) value;
2308 return 0;
2309 }
2310
2311 static void
2312 Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
2313 {
2314 (void) dpy;
2315 (void) drawable;
2316 (void) mask;
2317 }
2318
2319 static void
2320 Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
2321 {
2322 (void) dpy;
2323 (void) drawable;
2324 (void) mask;
2325 }
2326
2327
2328
2329 /*** GLX_SGI_cushion ***/
2330
2331 static void
2332 Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
2333 {
2334 (void) dpy;
2335 (void) win;
2336 (void) cushion;
2337 }
2338
2339
2340
2341 /*** GLX_SGIX_video_resize ***/
2342
2343 static int
2344 Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
2345 {
2346 (void) dpy;
2347 (void) screen;
2348 (void) channel;
2349 (void) window;
2350 return 0;
2351 }
2352
2353 static int
2354 Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
2355 {
2356 (void) dpy;
2357 (void) screen;
2358 (void) channel;
2359 (void) x;
2360 (void) y;
2361 (void) w;
2362 (void) h;
2363 return 0;
2364 }
2365
2366 static int
2367 Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
2368 {
2369 (void) dpy;
2370 (void) screen;
2371 (void) channel;
2372 (void) x;
2373 (void) y;
2374 (void) w;
2375 (void) h;
2376 return 0;
2377 }
2378
2379 static int
2380 Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
2381 {
2382 (void) dpy;
2383 (void) screen;
2384 (void) channel;
2385 (void) dx;
2386 (void) dy;
2387 (void) dw;
2388 (void) dh;
2389 return 0;
2390 }
2391
2392 static int
2393 Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
2394 {
2395 (void) dpy;
2396 (void) screen;
2397 (void) channel;
2398 (void) synctype;
2399 return 0;
2400 }
2401
2402
2403
2404 /*** GLX_SGIX_dmbuffer **/
2405
2406 #if defined(_DM_BUFFER_H_)
2407 static Bool
2408 Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
2409 {
2410 (void) dpy;
2411 (void) pbuffer;
2412 (void) params;
2413 (void) dmbuffer;
2414 return False;
2415 }
2416 #endif
2417
2418
2419 /*** GLX_SGIX_swap_group ***/
2420
2421 static void
2422 Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
2423 {
2424 (void) dpy;
2425 (void) drawable;
2426 (void) member;
2427 }
2428
2429
2430
2431 /*** GLX_SGIX_swap_barrier ***/
2432
2433 static void
2434 Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
2435 {
2436 (void) dpy;
2437 (void) drawable;
2438 (void) barrier;
2439 }
2440
2441 static Bool
2442 Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
2443 {
2444 (void) dpy;
2445 (void) screen;
2446 (void) max;
2447 return False;
2448 }
2449
2450
2451
2452 /*** GLX_SUN_get_transparent_index ***/
2453
2454 static Status
2455 Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
2456 {
2457 (void) dpy;
2458 (void) overlay;
2459 (void) underlay;
2460 (void) pTransparent;
2461 return 0;
2462 }
2463
2464
2465
2466 /*** GLX_MESA_release_buffers ***/
2467
2468 /*
2469 * Release the depth, stencil, accum buffers attached to a GLXDrawable
2470 * (a window or pixmap) prior to destroying the GLXDrawable.
2471 */
2472 static Bool
2473 Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
2474 {
2475 XMesaBuffer b = XMesaFindBuffer(dpy, d);
2476 if (b) {
2477 XMesaDestroyBuffer(b);
2478 return True;
2479 }
2480 return False;
2481 }
2482
2483
2484
2485 /*** GLX_MESA_set_3dfx_mode ***/
2486
2487 static Bool
2488 Fake_glXSet3DfxModeMESA( int mode )
2489 {
2490 return XMesaSetFXmode( mode );
2491 }
2492
2493
2494
2495 /*** AGP memory allocation ***/
2496 static void *
2497 Fake_glXAllocateMemoryNV( GLsizei size,
2498 GLfloat readFrequency,
2499 GLfloat writeFrequency,
2500 GLfloat priority )
2501 {
2502 (void) size;
2503 (void) readFrequency;
2504 (void) writeFrequency;
2505 (void) priority;
2506 return NULL;
2507 }
2508
2509
2510 static void
2511 Fake_glXFreeMemoryNV( GLvoid *pointer )
2512 {
2513 (void) pointer;
2514 }
2515
2516
2517
2518 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
2519 struct _glxapi_table *_mesa_GetGLXDispatchTable(void)
2520 {
2521 static struct _glxapi_table glx;
2522
2523 /* be sure our dispatch table size <= libGL's table */
2524 {
2525 GLuint size = sizeof(struct _glxapi_table) / sizeof(void *);
2526 (void) size;
2527 assert(_glxapi_get_dispatch_table_size() >= size);
2528 }
2529
2530 /* initialize the whole table to no-ops */
2531 _glxapi_set_no_op_table(&glx);
2532
2533 /* now initialize the table with the functions I implement */
2534 glx.ChooseVisual = Fake_glXChooseVisual;
2535 glx.CopyContext = Fake_glXCopyContext;
2536 glx.CreateContext = Fake_glXCreateContext;
2537 glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap;
2538 glx.DestroyContext = Fake_glXDestroyContext;
2539 glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap;
2540 glx.GetConfig = Fake_glXGetConfig;
2541 /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/
2542 /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/
2543 glx.IsDirect = Fake_glXIsDirect;
2544 glx.MakeCurrent = Fake_glXMakeCurrent;
2545 glx.QueryExtension = Fake_glXQueryExtension;
2546 glx.QueryVersion = Fake_glXQueryVersion;
2547 glx.SwapBuffers = Fake_glXSwapBuffers;
2548 glx.UseXFont = Fake_glXUseXFont;
2549 glx.WaitGL = Fake_glXWaitGL;
2550 glx.WaitX = Fake_glXWaitX;
2551
2552 /*** GLX_VERSION_1_1 ***/
2553 glx.GetClientString = Fake_glXGetClientString;
2554 glx.QueryExtensionsString = Fake_glXQueryExtensionsString;
2555 glx.QueryServerString = Fake_glXQueryServerString;
2556
2557 /*** GLX_VERSION_1_2 ***/
2558 /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/
2559
2560 /*** GLX_VERSION_1_3 ***/
2561 glx.ChooseFBConfig = Fake_glXChooseFBConfig;
2562 glx.CreateNewContext = Fake_glXCreateNewContext;
2563 glx.CreatePbuffer = Fake_glXCreatePbuffer;
2564 glx.CreatePixmap = Fake_glXCreatePixmap;
2565 glx.CreateWindow = Fake_glXCreateWindow;
2566 glx.DestroyPbuffer = Fake_glXDestroyPbuffer;
2567 glx.DestroyPixmap = Fake_glXDestroyPixmap;
2568 glx.DestroyWindow = Fake_glXDestroyWindow;
2569 /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/
2570 glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib;
2571 glx.GetFBConfigs = Fake_glXGetFBConfigs;
2572 glx.GetSelectedEvent = Fake_glXGetSelectedEvent;
2573 glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig;
2574 glx.MakeContextCurrent = Fake_glXMakeContextCurrent;
2575 glx.QueryContext = Fake_glXQueryContext;
2576 glx.QueryDrawable = Fake_glXQueryDrawable;
2577 glx.SelectEvent = Fake_glXSelectEvent;
2578
2579 /*** GLX_SGI_swap_control ***/
2580 glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI;
2581
2582 /*** GLX_SGI_video_sync ***/
2583 glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI;
2584 glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI;
2585
2586 /*** GLX_SGI_make_current_read ***/
2587 glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI;
2588 /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/
2589
2590 /*** GLX_SGIX_video_source ***/
2591 #if defined(_VL_H)
2592 glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX;
2593 glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX;
2594 #endif
2595
2596 /*** GLX_EXT_import_context ***/
2597 glx.FreeContextEXT = Fake_glXFreeContextEXT;
2598 glx.GetContextIDEXT = Fake_glXGetContextIDEXT;
2599 /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/
2600 glx.ImportContextEXT = Fake_glXImportContextEXT;
2601 glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT;
2602
2603 /*** GLX_SGIX_fbconfig ***/
2604 glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX;
2605 glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX;
2606 glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX;
2607 glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX;
2608 glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX;
2609 glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX;
2610
2611 /*** GLX_SGIX_pbuffer ***/
2612 glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX;
2613 glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX;
2614 glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX;
2615 glx.SelectEventSGIX = Fake_glXSelectEventSGIX;
2616 glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX;
2617
2618 /*** GLX_SGI_cushion ***/
2619 glx.CushionSGI = Fake_glXCushionSGI;
2620
2621 /*** GLX_SGIX_video_resize ***/
2622 glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX;
2623 glx.ChannelRectSGIX = Fake_glXChannelRectSGIX;
2624 glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX;
2625 glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX;
2626 glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX;
2627
2628 /*** GLX_SGIX_dmbuffer **/
2629 #if defined(_DM_BUFFER_H_)
2630 glx.AssociateDMPbufferSGIX = NULL;
2631 #endif
2632
2633 /*** GLX_SGIX_swap_group ***/
2634 glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX;
2635
2636 /*** GLX_SGIX_swap_barrier ***/
2637 glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX;
2638 glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX;
2639
2640 /*** GLX_SUN_get_transparent_index ***/
2641 glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN;
2642
2643 /*** GLX_MESA_copy_sub_buffer ***/
2644 glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA;
2645
2646 /*** GLX_MESA_release_buffers ***/
2647 glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA;
2648
2649 /*** GLX_MESA_pixmap_colormap ***/
2650 glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA;
2651
2652 /*** GLX_MESA_set_3dfx_mode ***/
2653 glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA;
2654
2655 /*** GLX AGP memory allocation ***/
2656 glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV;
2657 glx.FreeMemoryNV = Fake_glXFreeMemoryNV;
2658
2659 return &glx;
2660 }