Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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