~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/x11/fakeglx.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

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