Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice including the dates of first publication and
13
 * either this permission notice or a reference to
14
 * http://oss.sgi.com/projects/FreeB/
15
 * shall be included 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
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 *
25
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26
 * shall not be used in advertising or otherwise to promote the sale, use or
27
 * other dealings in this Software without prior written authorization from
28
 * Silicon Graphics, Inc.
29
 */
30
 
31
/**
32
 * \file glxcmds.c
33
 * Client-side GLX interface.
34
 */
35
 
36
#include "glxclient.h"
37
#include "glapi.h"
38
#include "glxextensions.h"
39
#include "indirect.h"
40
#include "glx_error.h"
41
 
42
#ifdef GLX_DIRECT_RENDERING
43
#ifdef GLX_USE_APPLEGL
44
#include "apple/apple_glx_context.h"
45
#include "apple/apple_glx.h"
46
#else
47
#include 
48
#ifdef XF86VIDMODE
49
#include 
50
#endif
51
#endif
52
#endif
53
 
54
#include 
55
#include 
56
#include 
57
 
58
static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
59
static const char __glXGLXClientVersion[] = "1.4";
60
 
61
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
62
 
63
/**
64
 * Get the __DRIdrawable for the drawable associated with a GLXContext
65
 *
66
 * \param dpy       The display associated with \c drawable.
67
 * \param drawable  GLXDrawable whose __DRIdrawable part is to be retrieved.
68
 * \param scrn_num  If non-NULL, the drawables screen is stored there
69
 * \returns  A pointer to the context's __DRIdrawable on success, or NULL if
70
 *           the drawable is not associated with a direct-rendering context.
71
 */
72
_X_HIDDEN __GLXDRIdrawable *
73
GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable)
74
{
75
   struct glx_display *priv = __glXInitialize(dpy);
76
   __GLXDRIdrawable *pdraw;
77
 
78
   if (priv == NULL)
79
      return NULL;
80
 
81
   if (__glxHashLookup(priv->drawHash, drawable, (void *) &pdraw) == 0)
82
      return pdraw;
83
 
84
   return NULL;
85
}
86
 
87
#endif
88
 
89
_X_HIDDEN struct glx_drawable *
90
GetGLXDrawable(Display *dpy, GLXDrawable drawable)
91
{
92
   struct glx_display *priv = __glXInitialize(dpy);
93
   struct glx_drawable *glxDraw;
94
 
95
   if (priv == NULL)
96
      return NULL;
97
 
98
   if (__glxHashLookup(priv->glXDrawHash, drawable, (void *) &glxDraw) == 0)
99
      return glxDraw;
100
 
101
   return NULL;
102
}
103
 
104
_X_HIDDEN int
105
InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable,
106
		GLXDrawable drawable)
107
{
108
   struct glx_display *priv = __glXInitialize(dpy);
109
 
110
   if (!priv)
111
      return -1;
112
 
113
   glxDraw->xDrawable = xDrawable;
114
   glxDraw->drawable = drawable;
115
   glxDraw->lastEventSbc = 0;
116
   glxDraw->eventSbcWrap = 0;
117
 
118
   return __glxHashInsert(priv->glXDrawHash, drawable, glxDraw);
119
}
120
 
121
_X_HIDDEN void
122
DestroyGLXDrawable(Display *dpy, GLXDrawable drawable)
123
{
124
   struct glx_display *priv = __glXInitialize(dpy);
125
   struct glx_drawable *glxDraw;
126
 
127
   if (!priv)
128
      return;
129
 
130
   glxDraw = GetGLXDrawable(dpy, drawable);
131
   __glxHashDelete(priv->glXDrawHash, drawable);
132
   free(glxDraw);
133
}
134
 
135
/**
136
 * Get the GLX per-screen data structure associated with a GLX context.
137
 *
138
 * \param dpy   Display for which the GLX per-screen information is to be
139
 *              retrieved.
140
 * \param scrn  Screen on \c dpy for which the GLX per-screen information is
141
 *              to be retrieved.
142
 * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn
143
 *          specify a valid GLX screen, or NULL otherwise.
144
 *
145
 * \todo Should this function validate that \c scrn is within the screen
146
 *       number range for \c dpy?
147
 */
148
 
149
_X_HIDDEN struct glx_screen *
150
GetGLXScreenConfigs(Display * dpy, int scrn)
151
{
152
   struct glx_display *const priv = __glXInitialize(dpy);
153
 
154
   return (priv
155
           && priv->screens !=
156
           NULL) ? priv->screens[scrn] : NULL;
157
}
158
 
159
 
160
static int
161
GetGLXPrivScreenConfig(Display * dpy, int scrn, struct glx_display ** ppriv,
162
                       struct glx_screen ** ppsc)
163
{
164
   /* Initialize the extension, if needed .  This has the added value
165
    * of initializing/allocating the display private
166
    */
167
 
168
   if (dpy == NULL) {
169
      return GLX_NO_EXTENSION;
170
   }
171
 
172
   *ppriv = __glXInitialize(dpy);
173
   if (*ppriv == NULL) {
174
      return GLX_NO_EXTENSION;
175
   }
176
 
177
   /* Check screen number to see if its valid */
178
   if ((scrn < 0) || (scrn >= ScreenCount(dpy))) {
179
      return GLX_BAD_SCREEN;
180
   }
181
 
182
   /* Check to see if the GL is supported on this screen */
183
   *ppsc = (*ppriv)->screens[scrn];
184
   if ((*ppsc)->configs == NULL && (*ppsc)->visuals == NULL) {
185
      /* No support for GL on this screen regardless of visual */
186
      return GLX_BAD_VISUAL;
187
   }
188
 
189
   return Success;
190
}
191
 
192
 
193
/**
194
 * Determine if a \c GLXFBConfig supplied by the application is valid.
195
 *
196
 * \param dpy     Application supplied \c Display pointer.
197
 * \param config  Application supplied \c GLXFBConfig.
198
 *
199
 * \returns If the \c GLXFBConfig is valid, the a pointer to the matching
200
 *          \c struct glx_config structure is returned.  Otherwise, \c NULL
201
 *          is returned.
202
 */
203
static struct glx_config *
204
ValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig)
205
{
206
   struct glx_display *const priv = __glXInitialize(dpy);
207
   int num_screens = ScreenCount(dpy);
208
   unsigned i;
209
   struct glx_config *config;
210
 
211
   if (priv != NULL) {
212
      for (i = 0; i < num_screens; i++) {
213
	 for (config = priv->screens[i]->configs; config != NULL;
214
	      config = config->next) {
215
	    if (config == (struct glx_config *) fbconfig) {
216
	       return config;
217
	    }
218
	 }
219
      }
220
   }
221
 
222
   return NULL;
223
}
224
 
225
/**
226
 * Verifies context's GLX_RENDER_TYPE value with config.
227
 *
228
 * \param config GLX FBConfig which will support the returned renderType.
229
 * \param renderType The context render type to be verified.
230
 * \return True if the value of context renderType was approved, or 0 if no
231
 * valid value was found.
232
 */
233
Bool
234
validate_renderType_against_config(const struct glx_config *config,
235
                                   int renderType)
236
{
237
    switch (renderType) {
238
    case GLX_RGBA_TYPE:
239
        return (config->renderType & GLX_RGBA_BIT) != 0;
240
    case GLX_COLOR_INDEX_TYPE:
241
        return (config->renderType & GLX_COLOR_INDEX_BIT) != 0;
242
    case GLX_RGBA_FLOAT_TYPE_ARB:
243
        return (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) != 0;
244
    case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT:
245
        return (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) != 0;
246
    default:
247
        break;
248
    }
249
    return 0;
250
}
251
 
252
_X_HIDDEN Bool
253
glx_context_init(struct glx_context *gc,
254
		 struct glx_screen *psc, struct glx_config *config)
255
{
256
   gc->majorOpcode = __glXSetupForCommand(psc->display->dpy);
257
   if (!gc->majorOpcode)
258
      return False;
259
 
260
   gc->screen = psc->scr;
261
   gc->psc = psc;
262
   gc->config = config;
263
   gc->isDirect = GL_TRUE;
264
   gc->currentContextTag = -1;
265
 
266
   return True;
267
}
268
 
269
 
270
/**
271
 * Create a new context.
272
 *
273
 * \param renderType   For FBConfigs, what is the rendering type?
274
 */
275
 
276
static GLXContext
277
CreateContext(Display *dpy, int generic_id, struct glx_config *config,
278
              GLXContext shareList_user, Bool allowDirect,
279
	      unsigned code, int renderType, int screen)
280
{
281
   struct glx_context *gc;
282
   struct glx_screen *psc;
283
   struct glx_context *shareList = (struct glx_context *) shareList_user;
284
   if (dpy == NULL)
285
      return NULL;
286
 
287
   psc = GetGLXScreenConfigs(dpy, screen);
288
   if (psc == NULL)
289
      return NULL;
290
 
291
   if (generic_id == None)
292
      return NULL;
293
 
294
   gc = NULL;
295
#ifdef GLX_USE_APPLEGL
296
   gc = applegl_create_context(psc, config, shareList, renderType);
297
#else
298
   if (allowDirect && psc->vtable->create_context)
299
      gc = psc->vtable->create_context(psc, config, shareList, renderType);
300
   if (!gc)
301
      gc = indirect_create_context(psc, config, shareList, renderType);
302
#endif
303
   if (!gc)
304
      return NULL;
305
 
306
   LockDisplay(dpy);
307
   switch (code) {
308
   case X_GLXCreateContext: {
309
      xGLXCreateContextReq *req;
310
 
311
      /* Send the glXCreateContext request */
312
      GetReq(GLXCreateContext, req);
313
      req->reqType = gc->majorOpcode;
314
      req->glxCode = X_GLXCreateContext;
315
      req->context = gc->xid = XAllocID(dpy);
316
      req->visual = generic_id;
317
      req->screen = screen;
318
      req->shareList = shareList ? shareList->xid : None;
319
      req->isDirect = gc->isDirect;
320
      break;
321
   }
322
 
323
   case X_GLXCreateNewContext: {
324
      xGLXCreateNewContextReq *req;
325
 
326
      /* Send the glXCreateNewContext request */
327
      GetReq(GLXCreateNewContext, req);
328
      req->reqType = gc->majorOpcode;
329
      req->glxCode = X_GLXCreateNewContext;
330
      req->context = gc->xid = XAllocID(dpy);
331
      req->fbconfig = generic_id;
332
      req->screen = screen;
333
      req->renderType = renderType;
334
      req->shareList = shareList ? shareList->xid : None;
335
      req->isDirect = gc->isDirect;
336
      break;
337
   }
338
 
339
   case X_GLXvop_CreateContextWithConfigSGIX: {
340
      xGLXVendorPrivateWithReplyReq *vpreq;
341
      xGLXCreateContextWithConfigSGIXReq *req;
342
 
343
      /* Send the glXCreateNewContext request */
344
      GetReqExtra(GLXVendorPrivateWithReply,
345
		  sz_xGLXCreateContextWithConfigSGIXReq -
346
		  sz_xGLXVendorPrivateWithReplyReq, vpreq);
347
      req = (xGLXCreateContextWithConfigSGIXReq *) vpreq;
348
      req->reqType = gc->majorOpcode;
349
      req->glxCode = X_GLXVendorPrivateWithReply;
350
      req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
351
      req->context = gc->xid = XAllocID(dpy);
352
      req->fbconfig = generic_id;
353
      req->screen = screen;
354
      req->renderType = renderType;
355
      req->shareList = shareList ? shareList->xid : None;
356
      req->isDirect = gc->isDirect;
357
      break;
358
   }
359
 
360
   default:
361
      /* What to do here?  This case is the sign of an internal error.  It
362
       * should never be reachable.
363
       */
364
      break;
365
   }
366
 
367
   UnlockDisplay(dpy);
368
   SyncHandle();
369
 
370
   gc->share_xid = shareList ? shareList->xid : None;
371
   gc->imported = GL_FALSE;
372
 
373
   return (GLXContext) gc;
374
}
375
 
376
_X_EXPORT GLXContext
377
glXCreateContext(Display * dpy, XVisualInfo * vis,
378
                 GLXContext shareList, Bool allowDirect)
379
{
380
   struct glx_config *config = NULL;
381
   int renderType = GLX_RGBA_TYPE;
382
 
383
#if defined(GLX_DIRECT_RENDERING) || defined(GLX_USE_APPLEGL)
384
   struct glx_screen *const psc = GetGLXScreenConfigs(dpy, vis->screen);
385
 
386
   if (psc)
387
      config = glx_config_find_visual(psc->visuals, vis->visualid);
388
 
389
   if (config == NULL) {
390
      xError error;
391
 
392
      error.errorCode = BadValue;
393
      error.resourceID = vis->visualid;
394
      error.sequenceNumber = dpy->request;
395
      error.type = X_Error;
396
      error.majorCode = __glXSetupForCommand(dpy);
397
      error.minorCode = X_GLXCreateContext;
398
      _XError(dpy, &error);
399
      return None;
400
   }
401
 
402
   /* Choose the context render type based on DRI config values.  It is
403
    * unusual to set this type from config, but we have no other choice, as
404
    * this old API does not provide renderType parameter.
405
    */
406
   if (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) {
407
       renderType = GLX_RGBA_FLOAT_TYPE_ARB;
408
   } else if (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) {
409
       renderType = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT;
410
   } else if (config->renderType & GLX_RGBA_BIT) {
411
       renderType = GLX_RGBA_TYPE;
412
   } else if (config->renderType & GLX_COLOR_INDEX_BIT) {
413
       renderType = GLX_COLOR_INDEX_TYPE;
414
   } else if (config->rgbMode) {
415
       /* If we're here, then renderType is not set correctly.  Let's use a
416
        * safeguard - any TrueColor or DirectColor mode is RGB mode.  Such
417
        * default value is needed by old DRI drivers, which didn't set
418
        * renderType correctly as the value was just ignored.
419
        */
420
       renderType = GLX_RGBA_TYPE;
421
   } else {
422
       /* Safeguard - only one option left, all non-RGB modes are indexed
423
        * modes.  Again, this allows drivers with invalid renderType to work
424
        * properly.
425
        */
426
       renderType = GLX_COLOR_INDEX_TYPE;
427
   }
428
#endif
429
 
430
   return CreateContext(dpy, vis->visualid, config, shareList, allowDirect,
431
                        X_GLXCreateContext, renderType, vis->screen);
432
}
433
 
434
static void
435
glx_send_destroy_context(Display *dpy, XID xid)
436
{
437
   CARD8 opcode = __glXSetupForCommand(dpy);
438
   xGLXDestroyContextReq *req;
439
 
440
   LockDisplay(dpy);
441
   GetReq(GLXDestroyContext, req);
442
   req->reqType = opcode;
443
   req->glxCode = X_GLXDestroyContext;
444
   req->context = xid;
445
   UnlockDisplay(dpy);
446
   SyncHandle();
447
}
448
 
449
/*
450
** Destroy the named context
451
*/
452
 
453
_X_EXPORT void
454
glXDestroyContext(Display * dpy, GLXContext ctx)
455
{
456
   struct glx_context *gc = (struct glx_context *) ctx;
457
 
458
   if (gc == NULL || gc->xid == None)
459
      return;
460
 
461
   __glXLock();
462
   if (!gc->imported)
463
      glx_send_destroy_context(dpy, gc->xid);
464
 
465
   if (gc->currentDpy) {
466
      /* This context is bound to some thread.  According to the man page,
467
       * we should not actually delete the context until it's unbound.
468
       * Note that we set gc->xid = None above.  In MakeContextCurrent()
469
       * we check for that and delete the context there.
470
       */
471
      gc->xid = None;
472
   } else {
473
      gc->vtable->destroy(gc);
474
   }
475
   __glXUnlock();
476
}
477
 
478
/*
479
** Return the major and minor version #s for the GLX extension
480
*/
481
_X_EXPORT Bool
482
glXQueryVersion(Display * dpy, int *major, int *minor)
483
{
484
   struct glx_display *priv;
485
 
486
   /* Init the extension.  This fetches the major and minor version. */
487
   priv = __glXInitialize(dpy);
488
   if (!priv)
489
      return False;
490
 
491
   if (major)
492
      *major = priv->majorVersion;
493
   if (minor)
494
      *minor = priv->minorVersion;
495
   return True;
496
}
497
 
498
/*
499
** Query the existence of the GLX extension
500
*/
501
_X_EXPORT Bool
502
glXQueryExtension(Display * dpy, int *errorBase, int *eventBase)
503
{
504
   int major_op, erb, evb;
505
   Bool rv;
506
 
507
   rv = XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_op, &evb, &erb);
508
   if (rv) {
509
      if (errorBase)
510
         *errorBase = erb;
511
      if (eventBase)
512
         *eventBase = evb;
513
   }
514
   return rv;
515
}
516
 
517
/*
518
** Put a barrier in the token stream that forces the GL to finish its
519
** work before X can proceed.
520
*/
521
_X_EXPORT void
522
glXWaitGL(void)
523
{
524
   struct glx_context *gc = __glXGetCurrentContext();
525
 
526
   if (gc && gc->vtable->wait_gl)
527
      gc->vtable->wait_gl(gc);
528
}
529
 
530
/*
531
** Put a barrier in the token stream that forces X to finish its
532
** work before GL can proceed.
533
*/
534
_X_EXPORT void
535
glXWaitX(void)
536
{
537
   struct glx_context *gc = __glXGetCurrentContext();
538
 
539
   if (gc && gc->vtable->wait_x)
540
      gc->vtable->wait_x(gc);
541
}
542
 
543
_X_EXPORT void
544
glXUseXFont(Font font, int first, int count, int listBase)
545
{
546
   struct glx_context *gc = __glXGetCurrentContext();
547
 
548
   if (gc && gc->vtable->use_x_font)
549
      gc->vtable->use_x_font(gc, font, first, count, listBase);
550
}
551
 
552
/************************************************************************/
553
 
554
/*
555
** Copy the source context to the destination context using the
556
** attribute "mask".
557
*/
558
_X_EXPORT void
559
glXCopyContext(Display * dpy, GLXContext source_user,
560
	       GLXContext dest_user, unsigned long mask)
561
{
562
   struct glx_context *source = (struct glx_context *) source_user;
563
   struct glx_context *dest = (struct glx_context *) dest_user;
564
#ifdef GLX_USE_APPLEGL
565
   struct glx_context *gc = __glXGetCurrentContext();
566
   int errorcode;
567
   bool x11error;
568
 
569
   if(apple_glx_copy_context(gc->driContext, source->driContext, dest->driContext,
570
                             mask, &errorcode, &x11error)) {
571
      __glXSendError(dpy, errorcode, 0, X_GLXCopyContext, x11error);
572
   }
573
 
574
#else
575
   xGLXCopyContextReq *req;
576
   struct glx_context *gc = __glXGetCurrentContext();
577
   GLXContextTag tag;
578
   CARD8 opcode;
579
 
580
   opcode = __glXSetupForCommand(dpy);
581
   if (!opcode) {
582
      return;
583
   }
584
 
585
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
586
   if (gc->isDirect) {
587
      /* NOT_DONE: This does not work yet */
588
   }
589
#endif
590
 
591
   /*
592
    ** If the source is the current context, send its tag so that the context
593
    ** can be flushed before the copy.
594
    */
595
   if (source == gc && dpy == gc->currentDpy) {
596
      tag = gc->currentContextTag;
597
   }
598
   else {
599
      tag = 0;
600
   }
601
 
602
   /* Send the glXCopyContext request */
603
   LockDisplay(dpy);
604
   GetReq(GLXCopyContext, req);
605
   req->reqType = opcode;
606
   req->glxCode = X_GLXCopyContext;
607
   req->source = source ? source->xid : None;
608
   req->dest = dest ? dest->xid : None;
609
   req->mask = mask;
610
   req->contextTag = tag;
611
   UnlockDisplay(dpy);
612
   SyncHandle();
613
#endif /* GLX_USE_APPLEGL */
614
}
615
 
616
 
617
/**
618
 * Determine if a context uses direct rendering.
619
 *
620
 * \param dpy        Display where the context was created.
621
 * \param contextID  ID of the context to be tested.
622
 *
623
 * \returns \c True if the context is direct rendering or not.
624
 */
625
static Bool
626
__glXIsDirect(Display * dpy, GLXContextID contextID)
627
{
628
   CARD8 opcode;
629
   xcb_connection_t *c;
630
   xcb_generic_error_t *err;
631
   xcb_glx_is_direct_reply_t *reply;
632
   Bool is_direct;
633
 
634
   opcode = __glXSetupForCommand(dpy);
635
   if (!opcode) {
636
      return False;
637
   }
638
 
639
   c = XGetXCBConnection(dpy);
640
   reply = xcb_glx_is_direct_reply(c, xcb_glx_is_direct(c, contextID), &err);
641
   is_direct = (reply != NULL && reply->is_direct) ? True : False;
642
 
643
   if (err != NULL) {
644
      __glXSendErrorForXcb(dpy, err);
645
      free(err);
646
   }
647
 
648
   free(reply);
649
 
650
   return is_direct;
651
}
652
 
653
/**
654
 * \todo
655
 * Shouldn't this function \b always return \c False when
656
 * \c GLX_DIRECT_RENDERING is not defined?  Do we really need to bother with
657
 * the GLX protocol here at all?
658
 */
659
_X_EXPORT Bool
660
glXIsDirect(Display * dpy, GLXContext gc_user)
661
{
662
   struct glx_context *gc = (struct glx_context *) gc_user;
663
 
664
   if (!gc) {
665
      return False;
666
   }
667
   else if (gc->isDirect) {
668
      return True;
669
   }
670
#ifdef GLX_USE_APPLEGL  /* TODO: indirect on darwin */
671
   return False;
672
#else
673
   return __glXIsDirect(dpy, gc->xid);
674
#endif
675
}
676
 
677
_X_EXPORT GLXPixmap
678
glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
679
{
680
#ifdef GLX_USE_APPLEGL
681
   int screen = vis->screen;
682
   struct glx_screen *const psc = GetGLXScreenConfigs(dpy, screen);
683
   const struct glx_config *config;
684
 
685
   config = glx_config_find_visual(psc->visuals, vis->visualid);
686
 
687
   if(apple_glx_pixmap_create(dpy, vis->screen, pixmap, config))
688
      return None;
689
 
690
   return pixmap;
691
#else
692
   xGLXCreateGLXPixmapReq *req;
693
   struct glx_drawable *glxDraw;
694
   GLXPixmap xid;
695
   CARD8 opcode;
696
 
697
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
698
   struct glx_display *const priv = __glXInitialize(dpy);
699
 
700
   if (priv == NULL)
701
      return None;
702
#endif
703
 
704
   opcode = __glXSetupForCommand(dpy);
705
   if (!opcode) {
706
      return None;
707
   }
708
 
709
   glxDraw = malloc(sizeof(*glxDraw));
710
   if (!glxDraw)
711
      return None;
712
 
713
   /* Send the glXCreateGLXPixmap request */
714
   LockDisplay(dpy);
715
   GetReq(GLXCreateGLXPixmap, req);
716
   req->reqType = opcode;
717
   req->glxCode = X_GLXCreateGLXPixmap;
718
   req->screen = vis->screen;
719
   req->visual = vis->visualid;
720
   req->pixmap = pixmap;
721
   req->glxpixmap = xid = XAllocID(dpy);
722
   UnlockDisplay(dpy);
723
   SyncHandle();
724
 
725
   if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) {
726
      free(glxDraw);
727
      return None;
728
   }
729
 
730
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
731
   do {
732
      /* FIXME: Maybe delay __DRIdrawable creation until the drawable
733
       * is actually bound to a context... */
734
 
735
      __GLXDRIdrawable *pdraw;
736
      struct glx_screen *psc;
737
      struct glx_config *config;
738
 
739
      psc = priv->screens[vis->screen];
740
      if (psc->driScreen == NULL)
741
         return xid;
742
 
743
      config = glx_config_find_visual(psc->visuals, vis->visualid);
744
      pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config);
745
      if (pdraw == NULL) {
746
         fprintf(stderr, "failed to create pixmap\n");
747
         xid = None;
748
         break;
749
      }
750
 
751
      if (__glxHashInsert(priv->drawHash, xid, pdraw)) {
752
         (*pdraw->destroyDrawable) (pdraw);
753
         xid = None;
754
         break;
755
      }
756
   } while (0);
757
 
758
   if (xid == None) {
759
      xGLXDestroyGLXPixmapReq *dreq;
760
      LockDisplay(dpy);
761
      GetReq(GLXDestroyGLXPixmap, dreq);
762
      dreq->reqType = opcode;
763
      dreq->glxCode = X_GLXDestroyGLXPixmap;
764
      dreq->glxpixmap = xid;
765
      UnlockDisplay(dpy);
766
      SyncHandle();
767
   }
768
#endif
769
 
770
   return xid;
771
#endif
772
}
773
 
774
/*
775
** Destroy the named pixmap
776
*/
777
_X_EXPORT void
778
glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
779
{
780
#ifdef GLX_USE_APPLEGL
781
   if(apple_glx_pixmap_destroy(dpy, glxpixmap))
782
      __glXSendError(dpy, GLXBadPixmap, glxpixmap, X_GLXDestroyPixmap, false);
783
#else
784
   xGLXDestroyGLXPixmapReq *req;
785
   CARD8 opcode;
786
 
787
   opcode = __glXSetupForCommand(dpy);
788
   if (!opcode) {
789
      return;
790
   }
791
 
792
   /* Send the glXDestroyGLXPixmap request */
793
   LockDisplay(dpy);
794
   GetReq(GLXDestroyGLXPixmap, req);
795
   req->reqType = opcode;
796
   req->glxCode = X_GLXDestroyGLXPixmap;
797
   req->glxpixmap = glxpixmap;
798
   UnlockDisplay(dpy);
799
   SyncHandle();
800
 
801
   DestroyGLXDrawable(dpy, glxpixmap);
802
 
803
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
804
   {
805
      struct glx_display *const priv = __glXInitialize(dpy);
806
      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap);
807
 
808
      if (priv != NULL && pdraw != NULL) {
809
         (*pdraw->destroyDrawable) (pdraw);
810
         __glxHashDelete(priv->drawHash, glxpixmap);
811
      }
812
   }
813
#endif
814
#endif /* GLX_USE_APPLEGL */
815
}
816
 
817
_X_EXPORT void
818
glXSwapBuffers(Display * dpy, GLXDrawable drawable)
819
{
820
#ifdef GLX_USE_APPLEGL
821
   struct glx_context * gc = __glXGetCurrentContext();
822
   if(gc && apple_glx_is_current_drawable(dpy, gc->driContext, drawable)) {
823
      apple_glx_swap_buffers(gc->driContext);
824
   } else {
825
      __glXSendError(dpy, GLXBadCurrentWindow, 0, X_GLXSwapBuffers, false);
826
   }
827
#else
828
   struct glx_context *gc;
829
   GLXContextTag tag;
830
   CARD8 opcode;
831
   xcb_connection_t *c;
832
 
833
   gc = __glXGetCurrentContext();
834
 
835
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
836
   {
837
      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
838
 
839
      if (pdraw != NULL) {
840
         Bool flush = gc && drawable == gc->currentDrawable;
841
 
842
         (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0, flush);
843
         return;
844
      }
845
   }
846
#endif
847
 
848
   opcode = __glXSetupForCommand(dpy);
849
   if (!opcode) {
850
      return;
851
   }
852
 
853
   /*
854
    ** The calling thread may or may not have a current context.  If it
855
    ** does, send the context tag so the server can do a flush.
856
    */
857
   if ((gc != NULL) && (dpy == gc->currentDpy) &&
858
       ((drawable == gc->currentDrawable)
859
        || (drawable == gc->currentReadable))) {
860
      tag = gc->currentContextTag;
861
   }
862
   else {
863
      tag = 0;
864
   }
865
 
866
   c = XGetXCBConnection(dpy);
867
   xcb_glx_swap_buffers(c, tag, drawable);
868
   xcb_flush(c);
869
#endif /* GLX_USE_APPLEGL */
870
}
871
 
872
 
873
/*
874
** Return configuration information for the given display, screen and
875
** visual combination.
876
*/
877
_X_EXPORT int
878
glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute,
879
             int *value_return)
880
{
881
   struct glx_display *priv;
882
   struct glx_screen *psc;
883
   struct glx_config *config;
884
   int status;
885
 
886
   status = GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc);
887
   if (status == Success) {
888
      config = glx_config_find_visual(psc->visuals, vis->visualid);
889
 
890
      /* Lookup attribute after first finding a match on the visual */
891
      if (config != NULL) {
892
	 return glx_config_get(config, attribute, value_return);
893
      }
894
 
895
      status = GLX_BAD_VISUAL;
896
   }
897
 
898
   /*
899
    ** If we can't find the config for this visual, this visual is not
900
    ** supported by the OpenGL implementation on the server.
901
    */
902
   if ((status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL)) {
903
      *value_return = False;
904
      status = Success;
905
   }
906
 
907
   return status;
908
}
909
 
910
/************************************************************************/
911
 
912
static void
913
init_fbconfig_for_chooser(struct glx_config * config,
914
                          GLboolean fbconfig_style_tags)
915
{
916
   memset(config, 0, sizeof(struct glx_config));
917
   config->visualID = (XID) GLX_DONT_CARE;
918
   config->visualType = GLX_DONT_CARE;
919
 
920
   /* glXChooseFBConfig specifies different defaults for these properties than
921
    * glXChooseVisual.
922
    */
923
   if (fbconfig_style_tags) {
924
      config->rgbMode = GL_TRUE;
925
      config->doubleBufferMode = GLX_DONT_CARE;
926
      config->renderType = GLX_RGBA_BIT;
927
   }
928
 
929
   config->drawableType = GLX_WINDOW_BIT;
930
   config->visualRating = GLX_DONT_CARE;
931
   config->transparentPixel = GLX_NONE;
932
   config->transparentRed = GLX_DONT_CARE;
933
   config->transparentGreen = GLX_DONT_CARE;
934
   config->transparentBlue = GLX_DONT_CARE;
935
   config->transparentAlpha = GLX_DONT_CARE;
936
   config->transparentIndex = GLX_DONT_CARE;
937
 
938
   config->xRenderable = GLX_DONT_CARE;
939
   config->fbconfigID = (GLXFBConfigID) (GLX_DONT_CARE);
940
 
941
   config->swapMethod = GLX_DONT_CARE;
942
}
943
 
944
#define MATCH_DONT_CARE( param )        \
945
  do {                                  \
946
    if ( ((int) a-> param != (int) GLX_DONT_CARE)   \
947
         && (a-> param != b-> param) ) {        \
948
      return False;                             \
949
    }                                           \
950
  } while ( 0 )
951
 
952
#define MATCH_MINIMUM( param )                  \
953
  do {                                          \
954
    if ( ((int) a-> param != (int) GLX_DONT_CARE)	\
955
         && (a-> param > b-> param) ) {         \
956
      return False;                             \
957
    }                                           \
958
  } while ( 0 )
959
 
960
#define MATCH_EXACT( param )                    \
961
  do {                                          \
962
    if ( a-> param != b-> param) {              \
963
      return False;                             \
964
    }                                           \
965
  } while ( 0 )
966
 
967
/* Test that all bits from a are contained in b */
968
#define MATCH_MASK(param)			\
969
  do {						\
970
    if ( ((int) a-> param != (int) GLX_DONT_CARE)	\
971
         && ((a->param & ~b->param) != 0) ) {   \
972
      return False;				\
973
    }                                           \
974
  } while (0);
975
 
976
/**
977
 * Determine if two GLXFBConfigs are compatible.
978
 *
979
 * \param a  Application specified config to test.
980
 * \param b  Server specified config to test against \c a.
981
 */
982
static Bool
983
fbconfigs_compatible(const struct glx_config * const a,
984
                     const struct glx_config * const b)
985
{
986
   MATCH_DONT_CARE(doubleBufferMode);
987
   MATCH_DONT_CARE(visualType);
988
   MATCH_DONT_CARE(visualRating);
989
   MATCH_DONT_CARE(xRenderable);
990
   MATCH_DONT_CARE(fbconfigID);
991
   MATCH_DONT_CARE(swapMethod);
992
 
993
   MATCH_MINIMUM(rgbBits);
994
   MATCH_MINIMUM(numAuxBuffers);
995
   MATCH_MINIMUM(redBits);
996
   MATCH_MINIMUM(greenBits);
997
   MATCH_MINIMUM(blueBits);
998
   MATCH_MINIMUM(alphaBits);
999
   MATCH_MINIMUM(depthBits);
1000
   MATCH_MINIMUM(stencilBits);
1001
   MATCH_MINIMUM(accumRedBits);
1002
   MATCH_MINIMUM(accumGreenBits);
1003
   MATCH_MINIMUM(accumBlueBits);
1004
   MATCH_MINIMUM(accumAlphaBits);
1005
   MATCH_MINIMUM(sampleBuffers);
1006
   MATCH_MINIMUM(maxPbufferWidth);
1007
   MATCH_MINIMUM(maxPbufferHeight);
1008
   MATCH_MINIMUM(maxPbufferPixels);
1009
   MATCH_MINIMUM(samples);
1010
 
1011
   MATCH_DONT_CARE(stereoMode);
1012
   MATCH_EXACT(level);
1013
 
1014
   MATCH_MASK(drawableType);
1015
   MATCH_MASK(renderType);
1016
 
1017
   /* There is a bug in a few of the XFree86 DDX drivers.  They contain
1018
    * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
1019
    * Technically speaking, it is a bug in the DDX driver, but there is
1020
    * enough of an installed base to work around the problem here.  In any
1021
    * case, 0 is not a valid value of the transparent type, so we'll treat 0
1022
    * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
1023
    * 0 from the server to be a match to maintain backward compatibility with
1024
    * the (broken) drivers.
1025
    */
1026
 
1027
   if (a->transparentPixel != (int) GLX_DONT_CARE && a->transparentPixel != 0) {
1028
      if (a->transparentPixel == GLX_NONE) {
1029
         if (b->transparentPixel != GLX_NONE && b->transparentPixel != 0)
1030
            return False;
1031
      }
1032
      else {
1033
         MATCH_EXACT(transparentPixel);
1034
      }
1035
 
1036
      switch (a->transparentPixel) {
1037
      case GLX_TRANSPARENT_RGB:
1038
         MATCH_DONT_CARE(transparentRed);
1039
         MATCH_DONT_CARE(transparentGreen);
1040
         MATCH_DONT_CARE(transparentBlue);
1041
         MATCH_DONT_CARE(transparentAlpha);
1042
         break;
1043
 
1044
      case GLX_TRANSPARENT_INDEX:
1045
         MATCH_DONT_CARE(transparentIndex);
1046
         break;
1047
 
1048
      default:
1049
         break;
1050
      }
1051
   }
1052
 
1053
   return True;
1054
}
1055
 
1056
 
1057
/* There's some trickly language in the GLX spec about how this is supposed
1058
 * to work.  Basically, if a given component size is either not specified
1059
 * or the requested size is zero, it is supposed to act like PERFER_SMALLER.
1060
 * Well, that's really hard to do with the code as-is.  This behavior is
1061
 * closer to correct, but still not technically right.
1062
 */
1063
#define PREFER_LARGER_OR_ZERO(comp)             \
1064
  do {                                          \
1065
    if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
1066
      if ( ((*a)-> comp) == 0 ) {               \
1067
        return -1;                              \
1068
      }                                         \
1069
      else if ( ((*b)-> comp) == 0 ) {          \
1070
        return 1;                               \
1071
      }                                         \
1072
      else {                                    \
1073
        return ((*b)-> comp) - ((*a)-> comp) ;  \
1074
      }                                         \
1075
    }                                           \
1076
  } while( 0 )
1077
 
1078
#define PREFER_LARGER(comp)                     \
1079
  do {                                          \
1080
    if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
1081
      return ((*b)-> comp) - ((*a)-> comp) ;    \
1082
    }                                           \
1083
  } while( 0 )
1084
 
1085
#define PREFER_SMALLER(comp)                    \
1086
  do {                                          \
1087
    if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
1088
      return ((*a)-> comp) - ((*b)-> comp) ;    \
1089
    }                                           \
1090
  } while( 0 )
1091
 
1092
/**
1093
 * Compare two GLXFBConfigs.  This function is intended to be used as the
1094
 * compare function passed in to qsort.
1095
 *
1096
 * \returns If \c a is a "better" config, according to the specification of
1097
 *          SGIX_fbconfig, a number less than zero is returned.  If \c b is
1098
 *          better, then a number greater than zero is return.  If both are
1099
 *          equal, zero is returned.
1100
 * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1101
 */
1102
static int
1103
fbconfig_compare(struct glx_config **a, struct glx_config **b)
1104
{
1105
   /* The order of these comparisons must NOT change.  It is defined by
1106
    * the GLX 1.4 specification.
1107
    */
1108
 
1109
   PREFER_SMALLER(visualSelectGroup);
1110
 
1111
   /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
1112
    * GLX_NON_CONFORMANT_CONFIG.  It just so happens that this is the
1113
    * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
1114
    */
1115
   PREFER_SMALLER(visualRating);
1116
 
1117
   /* This isn't quite right.  It is supposed to compare the sum of the
1118
    * components the user specifically set minimums for.
1119
    */
1120
   PREFER_LARGER_OR_ZERO(redBits);
1121
   PREFER_LARGER_OR_ZERO(greenBits);
1122
   PREFER_LARGER_OR_ZERO(blueBits);
1123
   PREFER_LARGER_OR_ZERO(alphaBits);
1124
 
1125
   PREFER_SMALLER(rgbBits);
1126
 
1127
   if (((*a)->doubleBufferMode != (*b)->doubleBufferMode)) {
1128
      /* Prefer single-buffer.
1129
       */
1130
      return (!(*a)->doubleBufferMode) ? -1 : 1;
1131
   }
1132
 
1133
   PREFER_SMALLER(numAuxBuffers);
1134
 
1135
   PREFER_SMALLER(sampleBuffers);
1136
   PREFER_SMALLER(samples);
1137
 
1138
   PREFER_LARGER_OR_ZERO(depthBits);
1139
   PREFER_SMALLER(stencilBits);
1140
 
1141
   /* This isn't quite right.  It is supposed to compare the sum of the
1142
    * components the user specifically set minimums for.
1143
    */
1144
   PREFER_LARGER_OR_ZERO(accumRedBits);
1145
   PREFER_LARGER_OR_ZERO(accumGreenBits);
1146
   PREFER_LARGER_OR_ZERO(accumBlueBits);
1147
   PREFER_LARGER_OR_ZERO(accumAlphaBits);
1148
 
1149
   PREFER_SMALLER(visualType);
1150
 
1151
   /* None of the pbuffer or fbconfig specs say that this comparison needs
1152
    * to happen at all, but it seems like it should.
1153
    */
1154
   PREFER_LARGER(maxPbufferWidth);
1155
   PREFER_LARGER(maxPbufferHeight);
1156
   PREFER_LARGER(maxPbufferPixels);
1157
 
1158
   return 0;
1159
}
1160
 
1161
 
1162
/**
1163
 * Selects and sorts a subset of the supplied configs based on the attributes.
1164
 * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig,
1165
 * and \c glXChooseFBConfigSGIX.
1166
 *
1167
 * \param configs   Array of pointers to possible configs.  The elements of
1168
 *                  this array that do not meet the criteria will be set to
1169
 *                  NULL.  The remaining elements will be sorted according to
1170
 *                  the various visual / FBConfig selection rules.
1171
 * \param num_configs  Number of elements in the \c configs array.
1172
 * \param attribList   Attributes used select from \c configs.  This array is
1173
 *                     terminated by a \c None tag.  The array can either take
1174
 *                     the form expected by \c glXChooseVisual (where boolean
1175
 *                     tags do not have a value) or by \c glXChooseFBConfig
1176
 *                     (where every tag has a value).
1177
 * \param fbconfig_style_tags  Selects whether \c attribList is in
1178
 *                             \c glXChooseVisual style or
1179
 *                             \c glXChooseFBConfig style.
1180
 * \returns The number of valid elements left in \c configs.
1181
 *
1182
 * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1183
 */
1184
static int
1185
choose_visual(struct glx_config ** configs, int num_configs,
1186
              const int *attribList, GLboolean fbconfig_style_tags)
1187
{
1188
   struct glx_config test_config;
1189
   int base;
1190
   int i;
1191
 
1192
   /* This is a fairly direct implementation of the selection method
1193
    * described by GLX_SGIX_fbconfig.  Start by culling out all the
1194
    * configs that are not compatible with the selected parameter
1195
    * list.
1196
    */
1197
 
1198
   init_fbconfig_for_chooser(&test_config, fbconfig_style_tags);
1199
   __glXInitializeVisualConfigFromTags(&test_config, 512,
1200
                                       (const INT32 *) attribList,
1201
                                       GL_TRUE, fbconfig_style_tags);
1202
 
1203
   base = 0;
1204
   for (i = 0; i < num_configs; i++) {
1205
      if (fbconfigs_compatible(&test_config, configs[i])) {
1206
         configs[base] = configs[i];
1207
         base++;
1208
      }
1209
   }
1210
 
1211
   if (base == 0) {
1212
      return 0;
1213
   }
1214
 
1215
   if (base < num_configs) {
1216
      (void) memset(&configs[base], 0, sizeof(void *) * (num_configs - base));
1217
   }
1218
 
1219
   /* After the incompatible configs are removed, the resulting
1220
    * list is sorted according to the rules set out in the various
1221
    * specifications.
1222
    */
1223
 
1224
   qsort(configs, base, sizeof(struct glx_config *),
1225
         (int (*)(const void *, const void *)) fbconfig_compare);
1226
   return base;
1227
}
1228
 
1229
 
1230
 
1231
 
1232
/*
1233
** Return the visual that best matches the template.  Return None if no
1234
** visual matches the template.
1235
*/
1236
_X_EXPORT XVisualInfo *
1237
glXChooseVisual(Display * dpy, int screen, int *attribList)
1238
{
1239
   XVisualInfo *visualList = NULL;
1240
   struct glx_display *priv;
1241
   struct glx_screen *psc;
1242
   struct glx_config test_config;
1243
   struct glx_config *config;
1244
   struct glx_config *best_config = NULL;
1245
 
1246
   /*
1247
    ** Get a list of all visuals, return if list is empty
1248
    */
1249
   if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1250
      return None;
1251
   }
1252
 
1253
 
1254
   /*
1255
    ** Build a template from the defaults and the attribute list
1256
    ** Free visual list and return if an unexpected token is encountered
1257
    */
1258
   init_fbconfig_for_chooser(&test_config, GL_FALSE);
1259
   __glXInitializeVisualConfigFromTags(&test_config, 512,
1260
                                       (const INT32 *) attribList,
1261
                                       GL_TRUE, GL_FALSE);
1262
 
1263
   /*
1264
    ** Eliminate visuals that don't meet minimum requirements
1265
    ** Compute a score for those that do
1266
    ** Remember which visual, if any, got the highest score
1267
    ** If no visual is acceptable, return None
1268
    ** Otherwise, create an XVisualInfo list with just the selected X visual
1269
    ** and return this.
1270
    */
1271
   for (config = psc->visuals; config != NULL; config = config->next) {
1272
      if (fbconfigs_compatible(&test_config, config)
1273
          && ((best_config == NULL) ||
1274
              (fbconfig_compare (&config, &best_config) < 0))) {
1275
         XVisualInfo visualTemplate;
1276
         XVisualInfo *newList;
1277
         int i;
1278
 
1279
         visualTemplate.screen = screen;
1280
         visualTemplate.visualid = config->visualID;
1281
         newList = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask,
1282
                                  &visualTemplate, &i);
1283
 
1284
         if (newList) {
1285
            free(visualList);
1286
            visualList = newList;
1287
            best_config = config;
1288
         }
1289
      }
1290
   }
1291
 
1292
#ifdef GLX_USE_APPLEGL
1293
   if(visualList && getenv("LIBGL_DUMP_VISUALID")) {
1294
      printf("visualid 0x%lx\n", visualList[0].visualid);
1295
   }
1296
#endif
1297
 
1298
   return visualList;
1299
}
1300
 
1301
 
1302
_X_EXPORT const char *
1303
glXQueryExtensionsString(Display * dpy, int screen)
1304
{
1305
   struct glx_screen *psc;
1306
   struct glx_display *priv;
1307
 
1308
   if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1309
      return NULL;
1310
   }
1311
 
1312
   if (!psc->effectiveGLXexts) {
1313
      if (!psc->serverGLXexts) {
1314
         psc->serverGLXexts =
1315
            __glXQueryServerString(dpy, priv->majorOpcode, screen,
1316
                                   GLX_EXTENSIONS);
1317
      }
1318
 
1319
      __glXCalculateUsableExtensions(psc,
1320
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
1321
                                     (psc->driScreen != NULL),
1322
#else
1323
                                     GL_FALSE,
1324
#endif
1325
                                     priv->minorVersion);
1326
   }
1327
 
1328
   return psc->effectiveGLXexts;
1329
}
1330
 
1331
_X_EXPORT const char *
1332
glXGetClientString(Display * dpy, int name)
1333
{
1334
   (void) dpy;
1335
 
1336
   switch (name) {
1337
   case GLX_VENDOR:
1338
      return (__glXGLXClientVendorName);
1339
   case GLX_VERSION:
1340
      return (__glXGLXClientVersion);
1341
   case GLX_EXTENSIONS:
1342
      return (__glXGetClientExtensions());
1343
   default:
1344
      return NULL;
1345
   }
1346
}
1347
 
1348
_X_EXPORT const char *
1349
glXQueryServerString(Display * dpy, int screen, int name)
1350
{
1351
   struct glx_screen *psc;
1352
   struct glx_display *priv;
1353
   const char **str;
1354
 
1355
 
1356
   if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1357
      return NULL;
1358
   }
1359
 
1360
   switch (name) {
1361
   case GLX_VENDOR:
1362
      str = &priv->serverGLXvendor;
1363
      break;
1364
   case GLX_VERSION:
1365
      str = &priv->serverGLXversion;
1366
      break;
1367
   case GLX_EXTENSIONS:
1368
      str = &psc->serverGLXexts;
1369
      break;
1370
   default:
1371
      return NULL;
1372
   }
1373
 
1374
   if (*str == NULL) {
1375
      *str = __glXQueryServerString(dpy, priv->majorOpcode, screen, name);
1376
   }
1377
 
1378
   return *str;
1379
}
1380
 
1381
 
1382
/*
1383
** EXT_import_context
1384
*/
1385
 
1386
_X_EXPORT Display *
1387
glXGetCurrentDisplay(void)
1388
{
1389
   struct glx_context *gc = __glXGetCurrentContext();
1390
   if (NULL == gc)
1391
      return NULL;
1392
   return gc->currentDpy;
1393
}
1394
 
1395
_X_EXPORT
1396
GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
1397
          glXGetCurrentDisplay)
1398
 
1399
#ifndef GLX_USE_APPLEGL
1400
_X_EXPORT GLXContext
1401
glXImportContextEXT(Display *dpy, GLXContextID contextID)
1402
{
1403
   struct glx_display *priv = __glXInitialize(dpy);
1404
   struct glx_screen *psc = NULL;
1405
   xGLXQueryContextReply reply;
1406
   CARD8 opcode;
1407
   struct glx_context *ctx;
1408
 
1409
   /* This GLX implementation knows about 5 different properties, so
1410
    * allow the server to send us one of each.
1411
    */
1412
   int propList[5 * 2], *pProp, nPropListBytes;
1413
   int numProps;
1414
   int i, renderType;
1415
   XID share;
1416
   struct glx_config *mode;
1417
   uint32_t fbconfigID = 0;
1418
   uint32_t visualID = 0;
1419
   uint32_t screen = 0;
1420
   Bool got_screen = False;
1421
 
1422
   if (priv == NULL)
1423
      return NULL;
1424
 
1425
   /* The GLX_EXT_import_context spec says:
1426
    *
1427
    *     "If  does not refer to a valid context, then a BadContext
1428
    *     error is generated; if  refers to direct rendering
1429
    *     context then no error is generated but glXImportContextEXT returns
1430
    *     NULL."
1431
    *
1432
    * If contextID is None, generate BadContext on the client-side.  Other
1433
    * sorts of invalid contexts will be detected by the server in the
1434
    * __glXIsDirect call.
1435
    */
1436
   if (contextID == None) {
1437
      __glXSendError(dpy, GLXBadContext, contextID, X_GLXIsDirect, false);
1438
      return NULL;
1439
   }
1440
 
1441
   if (__glXIsDirect(dpy, contextID))
1442
      return NULL;
1443
 
1444
   opcode = __glXSetupForCommand(dpy);
1445
   if (!opcode)
1446
      return 0;
1447
 
1448
   /* Send the glXQueryContextInfoEXT request */
1449
   LockDisplay(dpy);
1450
 
1451
   if (priv->majorVersion > 1 || priv->minorVersion >= 3) {
1452
      xGLXQueryContextReq *req;
1453
 
1454
      GetReq(GLXQueryContext, req);
1455
 
1456
      req->reqType = opcode;
1457
      req->glxCode = X_GLXQueryContext;
1458
      req->context = contextID;
1459
   }
1460
   else {
1461
      xGLXVendorPrivateReq *vpreq;
1462
      xGLXQueryContextInfoEXTReq *req;
1463
 
1464
      GetReqExtra(GLXVendorPrivate,
1465
		  sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
1466
		  vpreq);
1467
      req = (xGLXQueryContextInfoEXTReq *) vpreq;
1468
      req->reqType = opcode;
1469
      req->glxCode = X_GLXVendorPrivateWithReply;
1470
      req->vendorCode = X_GLXvop_QueryContextInfoEXT;
1471
      req->context = contextID;
1472
   }
1473
 
1474
   _XReply(dpy, (xReply *) & reply, 0, False);
1475
 
1476
   if (reply.n <= __GLX_MAX_CONTEXT_PROPS)
1477
      nPropListBytes = reply.n * 2 * sizeof propList[0];
1478
   else
1479
      nPropListBytes = 0;
1480
   _XRead(dpy, (char *) propList, nPropListBytes);
1481
   UnlockDisplay(dpy);
1482
   SyncHandle();
1483
 
1484
   numProps = nPropListBytes / (2 * sizeof(propList[0]));
1485
   share = None;
1486
   mode = NULL;
1487
   renderType = GLX_RGBA_TYPE; /* By default, assume RGBA context */
1488
   pProp = propList;
1489
 
1490
   for (i = 0, pProp = propList; i < numProps; i++, pProp += 2)
1491
      switch (pProp[0]) {
1492
      case GLX_SCREEN:
1493
	 screen = pProp[1];
1494
	 got_screen = True;
1495
	 break;
1496
      case GLX_SHARE_CONTEXT_EXT:
1497
	 share = pProp[1];
1498
	 break;
1499
      case GLX_VISUAL_ID_EXT:
1500
	 visualID = pProp[1];
1501
	 break;
1502
      case GLX_FBCONFIG_ID:
1503
	 fbconfigID = pProp[1];
1504
	 break;
1505
      case GLX_RENDER_TYPE:
1506
	 renderType = pProp[1];
1507
	 break;
1508
      }
1509
 
1510
   if (!got_screen)
1511
      return NULL;
1512
 
1513
   psc = GetGLXScreenConfigs(dpy, screen);
1514
   if (psc == NULL)
1515
      return NULL;
1516
 
1517
   if (fbconfigID != 0) {
1518
      mode = glx_config_find_fbconfig(psc->configs, fbconfigID);
1519
   } else if (visualID != 0) {
1520
      mode = glx_config_find_visual(psc->visuals, visualID);
1521
   }
1522
 
1523
   if (mode == NULL)
1524
      return NULL;
1525
 
1526
   ctx = indirect_create_context(psc, mode, NULL, renderType);
1527
   if (ctx == NULL)
1528
      return NULL;
1529
 
1530
   ctx->xid = contextID;
1531
   ctx->imported = GL_TRUE;
1532
   ctx->share_xid = share;
1533
 
1534
   return (GLXContext) ctx;
1535
}
1536
 
1537
#endif
1538
 
1539
_X_EXPORT int
1540
glXQueryContext(Display * dpy, GLXContext ctx_user, int attribute, int *value)
1541
{
1542
   struct glx_context *ctx = (struct glx_context *) ctx_user;
1543
 
1544
   switch (attribute) {
1545
      case GLX_SHARE_CONTEXT_EXT:
1546
      *value = ctx->share_xid;
1547
      break;
1548
   case GLX_VISUAL_ID_EXT:
1549
      *value = ctx->config ? ctx->config->visualID : None;
1550
      break;
1551
   case GLX_SCREEN:
1552
      *value = ctx->screen;
1553
      break;
1554
   case GLX_FBCONFIG_ID:
1555
      *value = ctx->config ? ctx->config->fbconfigID : None;
1556
      break;
1557
   case GLX_RENDER_TYPE:
1558
      *value = ctx->renderType;
1559
      break;
1560
   default:
1561
      return GLX_BAD_ATTRIBUTE;
1562
   }
1563
   return Success;
1564
}
1565
 
1566
_X_EXPORT
1567
GLX_ALIAS(int, glXQueryContextInfoEXT,
1568
          (Display * dpy, GLXContext ctx, int attribute, int *value),
1569
          (dpy, ctx, attribute, value), glXQueryContext)
1570
 
1571
_X_EXPORT GLXContextID glXGetContextIDEXT(const GLXContext ctx_user)
1572
{
1573
   struct glx_context *ctx = (struct glx_context *) ctx_user;
1574
 
1575
   return (ctx == NULL) ? None : ctx->xid;
1576
}
1577
 
1578
_X_EXPORT void
1579
glXFreeContextEXT(Display *dpy, GLXContext ctx)
1580
{
1581
   struct glx_context *gc = (struct glx_context *) ctx;
1582
 
1583
   if (gc == NULL || gc->xid == None)
1584
      return;
1585
 
1586
   /* The GLX_EXT_import_context spec says:
1587
    *
1588
    *     "glXFreeContext does not free the server-side context information or
1589
    *     the XID associated with the server-side context."
1590
    *
1591
    * Don't send any protocol.  Just destroy the client-side tracking of the
1592
    * context.  Also, only release the context structure if it's not current.
1593
    */
1594
   __glXLock();
1595
   if (gc->currentDpy) {
1596
      gc->xid = None;
1597
   } else {
1598
      gc->vtable->destroy(gc);
1599
   }
1600
   __glXUnlock();
1601
}
1602
 
1603
_X_EXPORT GLXFBConfig *
1604
glXChooseFBConfig(Display * dpy, int screen,
1605
                  const int *attribList, int *nitems)
1606
{
1607
   struct glx_config **config_list;
1608
   int list_size;
1609
 
1610
 
1611
   config_list = (struct glx_config **)
1612
      glXGetFBConfigs(dpy, screen, &list_size);
1613
 
1614
   if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) {
1615
      list_size = choose_visual(config_list, list_size, attribList, GL_TRUE);
1616
      if (list_size == 0) {
1617
         free(config_list);
1618
         config_list = NULL;
1619
      }
1620
   }
1621
 
1622
   *nitems = list_size;
1623
   return (GLXFBConfig *) config_list;
1624
}
1625
 
1626
 
1627
_X_EXPORT GLXContext
1628
glXCreateNewContext(Display * dpy, GLXFBConfig fbconfig,
1629
                    int renderType, GLXContext shareList, Bool allowDirect)
1630
{
1631
   struct glx_config *config = (struct glx_config *) fbconfig;
1632
 
1633
   return CreateContext(dpy, config->fbconfigID, config, shareList,
1634
			allowDirect, X_GLXCreateNewContext, renderType,
1635
			config->screen);
1636
}
1637
 
1638
 
1639
_X_EXPORT GLXDrawable
1640
glXGetCurrentReadDrawable(void)
1641
{
1642
   struct glx_context *gc = __glXGetCurrentContext();
1643
 
1644
   return gc->currentReadable;
1645
}
1646
 
1647
 
1648
_X_EXPORT GLXFBConfig *
1649
glXGetFBConfigs(Display * dpy, int screen, int *nelements)
1650
{
1651
   struct glx_display *priv = __glXInitialize(dpy);
1652
   struct glx_config **config_list = NULL;
1653
   struct glx_config *config;
1654
   unsigned num_configs = 0;
1655
   int i;
1656
 
1657
   *nelements = 0;
1658
   if (priv && (priv->screens != NULL)
1659
       && (screen >= 0) && (screen <= ScreenCount(dpy))
1660
       && (priv->screens[screen]->configs != NULL)
1661
       && (priv->screens[screen]->configs->fbconfigID
1662
	   != (int) GLX_DONT_CARE)) {
1663
 
1664
      for (config = priv->screens[screen]->configs; config != NULL;
1665
           config = config->next) {
1666
         if (config->fbconfigID != (int) GLX_DONT_CARE) {
1667
            num_configs++;
1668
         }
1669
      }
1670
 
1671
      config_list = malloc(num_configs * sizeof *config_list);
1672
      if (config_list != NULL) {
1673
         *nelements = num_configs;
1674
         i = 0;
1675
         for (config = priv->screens[screen]->configs; config != NULL;
1676
              config = config->next) {
1677
            if (config->fbconfigID != (int) GLX_DONT_CARE) {
1678
               config_list[i] = config;
1679
               i++;
1680
            }
1681
         }
1682
      }
1683
   }
1684
 
1685
   return (GLXFBConfig *) config_list;
1686
}
1687
 
1688
 
1689
_X_EXPORT int
1690
glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig,
1691
                     int attribute, int *value)
1692
{
1693
   struct glx_config *config = ValidateGLXFBConfig(dpy, fbconfig);
1694
 
1695
   if (config == NULL)
1696
      return GLXBadFBConfig;
1697
 
1698
   return glx_config_get(config, attribute, value);
1699
}
1700
 
1701
 
1702
_X_EXPORT XVisualInfo *
1703
glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig fbconfig)
1704
{
1705
   XVisualInfo visualTemplate;
1706
   struct glx_config *config = (struct glx_config *) fbconfig;
1707
   int count;
1708
 
1709
   /*
1710
    ** Get a list of all visuals, return if list is empty
1711
    */
1712
   visualTemplate.visualid = config->visualID;
1713
   return XGetVisualInfo(dpy, VisualIDMask, &visualTemplate, &count);
1714
}
1715
 
1716
#ifndef GLX_USE_APPLEGL
1717
/*
1718
** GLX_SGI_swap_control
1719
*/
1720
static int
1721
__glXSwapIntervalSGI(int interval)
1722
{
1723
   xGLXVendorPrivateReq *req;
1724
   struct glx_context *gc = __glXGetCurrentContext();
1725
   struct glx_screen *psc;
1726
   Display *dpy;
1727
   CARD32 *interval_ptr;
1728
   CARD8 opcode;
1729
 
1730
   if (gc == NULL) {
1731
      return GLX_BAD_CONTEXT;
1732
   }
1733
 
1734
   if (interval <= 0) {
1735
      return GLX_BAD_VALUE;
1736
   }
1737
 
1738
   psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1739
 
1740
#ifdef GLX_DIRECT_RENDERING
1741
   if (gc->isDirect && psc && psc->driScreen &&
1742
          psc->driScreen->setSwapInterval) {
1743
      __GLXDRIdrawable *pdraw =
1744
	 GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
1745
      psc->driScreen->setSwapInterval(pdraw, interval);
1746
      return 0;
1747
   }
1748
#endif
1749
 
1750
   dpy = gc->currentDpy;
1751
   opcode = __glXSetupForCommand(dpy);
1752
   if (!opcode) {
1753
      return 0;
1754
   }
1755
 
1756
   /* Send the glXSwapIntervalSGI request */
1757
   LockDisplay(dpy);
1758
   GetReqExtra(GLXVendorPrivate, sizeof(CARD32), req);
1759
   req->reqType = opcode;
1760
   req->glxCode = X_GLXVendorPrivate;
1761
   req->vendorCode = X_GLXvop_SwapIntervalSGI;
1762
   req->contextTag = gc->currentContextTag;
1763
 
1764
   interval_ptr = (CARD32 *) (req + 1);
1765
   *interval_ptr = interval;
1766
 
1767
   UnlockDisplay(dpy);
1768
   SyncHandle();
1769
   XFlush(dpy);
1770
 
1771
   return 0;
1772
}
1773
 
1774
 
1775
/*
1776
** GLX_MESA_swap_control
1777
*/
1778
static int
1779
__glXSwapIntervalMESA(unsigned int interval)
1780
{
1781
#ifdef GLX_DIRECT_RENDERING
1782
   struct glx_context *gc = __glXGetCurrentContext();
1783
 
1784
   if (gc != NULL && gc->isDirect) {
1785
      struct glx_screen *psc;
1786
 
1787
      psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1788
      if (psc && psc->driScreen && psc->driScreen->setSwapInterval) {
1789
         __GLXDRIdrawable *pdraw =
1790
	    GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
1791
	 return psc->driScreen->setSwapInterval(pdraw, interval);
1792
      }
1793
   }
1794
#endif
1795
 
1796
   return GLX_BAD_CONTEXT;
1797
}
1798
 
1799
 
1800
static int
1801
__glXGetSwapIntervalMESA(void)
1802
{
1803
#ifdef GLX_DIRECT_RENDERING
1804
   struct glx_context *gc = __glXGetCurrentContext();
1805
 
1806
   if (gc != NULL && gc->isDirect) {
1807
      struct glx_screen *psc;
1808
 
1809
      psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1810
      if (psc && psc->driScreen && psc->driScreen->getSwapInterval) {
1811
         __GLXDRIdrawable *pdraw =
1812
	    GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
1813
	 return psc->driScreen->getSwapInterval(pdraw);
1814
      }
1815
   }
1816
#endif
1817
 
1818
   return 0;
1819
}
1820
 
1821
 
1822
/*
1823
** GLX_SGI_video_sync
1824
*/
1825
static int
1826
__glXGetVideoSyncSGI(unsigned int *count)
1827
{
1828
   int64_t ust, msc, sbc;
1829
   int ret;
1830
   struct glx_context *gc = __glXGetCurrentContext();
1831
   struct glx_screen *psc;
1832
#ifdef GLX_DIRECT_RENDERING
1833
   __GLXDRIdrawable *pdraw;
1834
#endif
1835
 
1836
   if (!gc)
1837
      return GLX_BAD_CONTEXT;
1838
 
1839
#ifdef GLX_DIRECT_RENDERING
1840
   if (!gc->isDirect)
1841
      return GLX_BAD_CONTEXT;
1842
#endif
1843
 
1844
   psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen);
1845
#ifdef GLX_DIRECT_RENDERING
1846
   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
1847
#endif
1848
 
1849
   /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
1850
    * FIXME: there should be a GLX encoding for this call.  I can find no
1851
    * FIXME: documentation for the GLX encoding.
1852
    */
1853
#ifdef GLX_DIRECT_RENDERING
1854
   if (psc && psc->driScreen && psc->driScreen->getDrawableMSC) {
1855
      ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc);
1856
      *count = (unsigned) msc;
1857
      return (ret == True) ? 0 : GLX_BAD_CONTEXT;
1858
   }
1859
#endif
1860
 
1861
   return GLX_BAD_CONTEXT;
1862
}
1863
 
1864
static int
1865
__glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
1866
{
1867
   struct glx_context *gc = __glXGetCurrentContext();
1868
   struct glx_screen *psc;
1869
#ifdef GLX_DIRECT_RENDERING
1870
   __GLXDRIdrawable *pdraw;
1871
#endif
1872
   int64_t ust, msc, sbc;
1873
   int ret;
1874
 
1875
   if (divisor <= 0 || remainder < 0)
1876
      return GLX_BAD_VALUE;
1877
 
1878
   if (!gc)
1879
      return GLX_BAD_CONTEXT;
1880
 
1881
#ifdef GLX_DIRECT_RENDERING
1882
   if (!gc->isDirect)
1883
      return GLX_BAD_CONTEXT;
1884
#endif
1885
 
1886
   psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1887
#ifdef GLX_DIRECT_RENDERING
1888
   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
1889
#endif
1890
 
1891
#ifdef GLX_DIRECT_RENDERING
1892
   if (psc && psc->driScreen && psc->driScreen->waitForMSC) {
1893
      ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc,
1894
				       &sbc);
1895
      *count = (unsigned) msc;
1896
      return (ret == True) ? 0 : GLX_BAD_CONTEXT;
1897
   }
1898
#endif
1899
 
1900
   return GLX_BAD_CONTEXT;
1901
}
1902
 
1903
#endif /* GLX_USE_APPLEGL */
1904
 
1905
/*
1906
** GLX_SGIX_fbconfig
1907
** Many of these functions are aliased to GLX 1.3 entry points in the
1908
** GLX_functions table.
1909
*/
1910
 
1911
_X_EXPORT
1912
GLX_ALIAS(int, glXGetFBConfigAttribSGIX,
1913
          (Display * dpy, GLXFBConfigSGIX config, int attribute, int *value),
1914
          (dpy, config, attribute, value), glXGetFBConfigAttrib)
1915
 
1916
_X_EXPORT GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
1917
                 (Display * dpy, int screen, int *attrib_list,
1918
                  int *nelements), (dpy, screen, attrib_list, nelements),
1919
                 glXChooseFBConfig)
1920
 
1921
_X_EXPORT GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
1922
                 (Display * dpy, GLXFBConfigSGIX config),
1923
                 (dpy, config), glXGetVisualFromFBConfig)
1924
 
1925
_X_EXPORT GLXPixmap
1926
glXCreateGLXPixmapWithConfigSGIX(Display * dpy,
1927
                                 GLXFBConfigSGIX fbconfig,
1928
                                 Pixmap pixmap)
1929
{
1930
#ifndef GLX_USE_APPLEGL
1931
   xGLXVendorPrivateWithReplyReq *vpreq;
1932
   xGLXCreateGLXPixmapWithConfigSGIXReq *req;
1933
   GLXPixmap xid = None;
1934
   CARD8 opcode;
1935
   struct glx_screen *psc;
1936
#endif
1937
   struct glx_config *config = (struct glx_config *) fbconfig;
1938
 
1939
 
1940
   if ((dpy == NULL) || (config == NULL)) {
1941
      return None;
1942
   }
1943
#ifdef GLX_USE_APPLEGL
1944
   if(apple_glx_pixmap_create(dpy, config->screen, pixmap, config))
1945
      return None;
1946
   return pixmap;
1947
#else
1948
 
1949
   psc = GetGLXScreenConfigs(dpy, config->screen);
1950
   if ((psc != NULL)
1951
       && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
1952
      opcode = __glXSetupForCommand(dpy);
1953
      if (!opcode) {
1954
         return None;
1955
      }
1956
 
1957
      /* Send the glXCreateGLXPixmapWithConfigSGIX request */
1958
      LockDisplay(dpy);
1959
      GetReqExtra(GLXVendorPrivateWithReply,
1960
                  sz_xGLXCreateGLXPixmapWithConfigSGIXReq -
1961
                  sz_xGLXVendorPrivateWithReplyReq, vpreq);
1962
      req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) vpreq;
1963
      req->reqType = opcode;
1964
      req->glxCode = X_GLXVendorPrivateWithReply;
1965
      req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
1966
      req->screen = config->screen;
1967
      req->fbconfig = config->fbconfigID;
1968
      req->pixmap = pixmap;
1969
      req->glxpixmap = xid = XAllocID(dpy);
1970
      UnlockDisplay(dpy);
1971
      SyncHandle();
1972
   }
1973
 
1974
   return xid;
1975
#endif
1976
}
1977
 
1978
_X_EXPORT GLXContext
1979
glXCreateContextWithConfigSGIX(Display * dpy,
1980
                               GLXFBConfigSGIX fbconfig, int renderType,
1981
                               GLXContext shareList, Bool allowDirect)
1982
{
1983
   GLXContext gc = NULL;
1984
   struct glx_config *config = (struct glx_config *) fbconfig;
1985
   struct glx_screen *psc;
1986
 
1987
 
1988
   if ((dpy == NULL) || (config == NULL)) {
1989
      return None;
1990
   }
1991
 
1992
   psc = GetGLXScreenConfigs(dpy, config->screen);
1993
   if ((psc != NULL)
1994
       && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
1995
      gc = CreateContext(dpy, config->fbconfigID, config, shareList,
1996
                         allowDirect,
1997
			 X_GLXvop_CreateContextWithConfigSGIX, renderType,
1998
			 config->screen);
1999
   }
2000
 
2001
   return gc;
2002
}
2003
 
2004
 
2005
_X_EXPORT GLXFBConfigSGIX
2006
glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis)
2007
{
2008
   struct glx_display *priv;
2009
   struct glx_screen *psc = NULL;
2010
 
2011
   if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) == Success)
2012
       && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)
2013
       && (psc->configs->fbconfigID != (int) GLX_DONT_CARE)) {
2014
      return (GLXFBConfigSGIX) glx_config_find_visual(psc->configs,
2015
						      vis->visualid);
2016
   }
2017
 
2018
   return NULL;
2019
}
2020
 
2021
#ifndef GLX_USE_APPLEGL
2022
/*
2023
** GLX_SGIX_swap_group
2024
*/
2025
static void
2026
__glXJoinSwapGroupSGIX(Display * dpy, GLXDrawable drawable,
2027
                       GLXDrawable member)
2028
{
2029
   (void) dpy;
2030
   (void) drawable;
2031
   (void) member;
2032
}
2033
 
2034
 
2035
/*
2036
** GLX_SGIX_swap_barrier
2037
*/
2038
static void
2039
__glXBindSwapBarrierSGIX(Display * dpy, GLXDrawable drawable, int barrier)
2040
{
2041
   (void) dpy;
2042
   (void) drawable;
2043
   (void) barrier;
2044
}
2045
 
2046
static Bool
2047
__glXQueryMaxSwapBarriersSGIX(Display * dpy, int screen, int *max)
2048
{
2049
   (void) dpy;
2050
   (void) screen;
2051
   (void) max;
2052
   return False;
2053
}
2054
 
2055
 
2056
/*
2057
** GLX_OML_sync_control
2058
*/
2059
static Bool
2060
__glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
2061
                      int64_t * ust, int64_t * msc, int64_t * sbc)
2062
{
2063
   struct glx_display * const priv = __glXInitialize(dpy);
2064
   int ret;
2065
#ifdef GLX_DIRECT_RENDERING
2066
   __GLXDRIdrawable *pdraw;
2067
#endif
2068
   struct glx_screen *psc;
2069
 
2070
   if (!priv)
2071
      return False;
2072
 
2073
#ifdef GLX_DIRECT_RENDERING
2074
   pdraw = GetGLXDRIDrawable(dpy, drawable);
2075
   psc = pdraw ? pdraw->psc : NULL;
2076
   if (pdraw && psc->driScreen->getDrawableMSC) {
2077
      ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc);
2078
      return ret;
2079
   }
2080
#endif
2081
 
2082
   return False;
2083
}
2084
 
2085
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
2086
_X_HIDDEN GLboolean
2087
__glxGetMscRate(struct glx_screen *psc,
2088
		int32_t * numerator, int32_t * denominator)
2089
{
2090
#ifdef XF86VIDMODE
2091
   XF86VidModeModeLine mode_line;
2092
   int dot_clock;
2093
   int i;
2094
 
2095
   if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
2096
       XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line)) {
2097
      unsigned n = dot_clock * 1000;
2098
      unsigned d = mode_line.vtotal * mode_line.htotal;
2099
 
2100
# define V_INTERLACE 0x010
2101
# define V_DBLSCAN   0x020
2102
 
2103
      if (mode_line.flags & V_INTERLACE)
2104
         n *= 2;
2105
      else if (mode_line.flags & V_DBLSCAN)
2106
         d *= 2;
2107
 
2108
      /* The OML_sync_control spec requires that if the refresh rate is a
2109
       * whole number, that the returned numerator be equal to the refresh
2110
       * rate and the denominator be 1.
2111
       */
2112
 
2113
      if (n % d == 0) {
2114
         n /= d;
2115
         d = 1;
2116
      }
2117
      else {
2118
         static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
2119
 
2120
         /* This is a poor man's way to reduce a fraction.  It's far from
2121
          * perfect, but it will work well enough for this situation.
2122
          */
2123
 
2124
         for (i = 0; f[i] != 0; i++) {
2125
            while (n % f[i] == 0 && d % f[i] == 0) {
2126
               d /= f[i];
2127
               n /= f[i];
2128
            }
2129
         }
2130
      }
2131
 
2132
      *numerator = n;
2133
      *denominator = d;
2134
 
2135
      return True;
2136
   }
2137
   else
2138
#endif
2139
 
2140
   return False;
2141
}
2142
#endif
2143
 
2144
/**
2145
 * Determine the refresh rate of the specified drawable and display.
2146
 *
2147
 * \param dpy          Display whose refresh rate is to be determined.
2148
 * \param drawable     Drawable whose refresh rate is to be determined.
2149
 * \param numerator    Numerator of the refresh rate.
2150
 * \param demoninator  Denominator of the refresh rate.
2151
 * \return  If the refresh rate for the specified display and drawable could
2152
 *          be calculated, True is returned.  Otherwise False is returned.
2153
 *
2154
 * \note This function is implemented entirely client-side.  A lot of other
2155
 *       functionality is required to export GLX_OML_sync_control, so on
2156
 *       XFree86 this function can be called for direct-rendering contexts
2157
 *       when GLX_OML_sync_control appears in the client extension string.
2158
 */
2159
 
2160
_X_HIDDEN GLboolean
2161
__glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
2162
                   int32_t * numerator, int32_t * denominator)
2163
{
2164
#if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
2165
   __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable);
2166
 
2167
   if (draw == NULL)
2168
      return False;
2169
 
2170
   return __glxGetMscRate(draw->psc, numerator, denominator);
2171
#else
2172
   (void) dpy;
2173
   (void) drawable;
2174
   (void) numerator;
2175
   (void) denominator;
2176
#endif
2177
   return False;
2178
}
2179
 
2180
 
2181
static int64_t
2182
__glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
2183
                       int64_t target_msc, int64_t divisor, int64_t remainder)
2184
{
2185
   struct glx_context *gc = __glXGetCurrentContext();
2186
#ifdef GLX_DIRECT_RENDERING
2187
   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
2188
   struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
2189
#endif
2190
 
2191
   if (!gc) /* no GLX for this */
2192
      return -1;
2193
 
2194
#ifdef GLX_DIRECT_RENDERING
2195
   if (!pdraw || !gc->isDirect)
2196
      return -1;
2197
#endif
2198
 
2199
   /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2200
    * error", but it also says "It [glXSwapBuffersMscOML] will return a value
2201
    * of -1 if the function failed because of errors detected in the input
2202
    * parameters"
2203
    */
2204
   if (divisor < 0 || remainder < 0 || target_msc < 0)
2205
      return -1;
2206
   if (divisor > 0 && remainder >= divisor)
2207
      return -1;
2208
 
2209
   if (target_msc == 0 && divisor == 0 && remainder == 0)
2210
      remainder = 1;
2211
 
2212
#ifdef GLX_DIRECT_RENDERING
2213
   if (psc->driScreen && psc->driScreen->swapBuffers)
2214
      return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor,
2215
					    remainder, False);
2216
#endif
2217
 
2218
   return -1;
2219
}
2220
 
2221
 
2222
static Bool
2223
__glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
2224
                   int64_t target_msc, int64_t divisor,
2225
                   int64_t remainder, int64_t * ust,
2226
                   int64_t * msc, int64_t * sbc)
2227
{
2228
#ifdef GLX_DIRECT_RENDERING
2229
   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
2230
   struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
2231
   int ret;
2232
#endif
2233
 
2234
 
2235
   /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2236
    * error", but the return type in the spec is Bool.
2237
    */
2238
   if (divisor < 0 || remainder < 0 || target_msc < 0)
2239
      return False;
2240
   if (divisor > 0 && remainder >= divisor)
2241
      return False;
2242
 
2243
#ifdef GLX_DIRECT_RENDERING
2244
   if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
2245
      ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder,
2246
				       ust, msc, sbc);
2247
      return ret;
2248
   }
2249
#endif
2250
 
2251
   return False;
2252
}
2253
 
2254
 
2255
static Bool
2256
__glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
2257
                   int64_t target_sbc, int64_t * ust,
2258
                   int64_t * msc, int64_t * sbc)
2259
{
2260
#ifdef GLX_DIRECT_RENDERING
2261
   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
2262
   struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
2263
   int ret;
2264
#endif
2265
 
2266
   /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
2267
    * error", but the return type in the spec is Bool.
2268
    */
2269
   if (target_sbc < 0)
2270
      return False;
2271
 
2272
#ifdef GLX_DIRECT_RENDERING
2273
   if (pdraw && psc->driScreen && psc->driScreen->waitForSBC) {
2274
      ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc);
2275
      return ret;
2276
   }
2277
#endif
2278
 
2279
   return False;
2280
}
2281
 
2282
/*@}*/
2283
 
2284
 
2285
/**
2286
 * Mesa extension stubs.  These will help reduce portability problems.
2287
 */
2288
/*@{*/
2289
 
2290
/**
2291
 * Release all buffers associated with the specified GLX drawable.
2292
 *
2293
 * \todo
2294
 * This function was intended for stand-alone Mesa.  The issue there is that
2295
 * the library doesn't get any notification when a window is closed.  In
2296
 * DRI there is a similar but slightly different issue.  When GLX 1.3 is
2297
 * supported, there are 3 different functions to destroy a drawable.  It
2298
 * should be possible to create GLX protocol (or have it determine which
2299
 * protocol to use based on the type of the drawable) to have one function
2300
 * do the work of 3.  For the direct-rendering case, this function could
2301
 * just call the driver's \c __DRIdrawableRec::destroyDrawable function.
2302
 * This would reduce the frequency with which \c __driGarbageCollectDrawables
2303
 * would need to be used.  This really should be done as part of the new DRI
2304
 * interface work.
2305
 *
2306
 * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt
2307
 *     __driGarbageCollectDrawables
2308
 *     glXDestroyGLXPixmap
2309
 *     glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
2310
 *     glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
2311
 */
2312
static Bool
2313
__glXReleaseBuffersMESA(Display * dpy, GLXDrawable d)
2314
{
2315
   (void) dpy;
2316
   (void) d;
2317
   return False;
2318
}
2319
 
2320
 
2321
_X_EXPORT GLXPixmap
2322
glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual,
2323
                       Pixmap pixmap, Colormap cmap)
2324
{
2325
   (void) dpy;
2326
   (void) visual;
2327
   (void) pixmap;
2328
   (void) cmap;
2329
   return 0;
2330
}
2331
 
2332
/*@}*/
2333
 
2334
 
2335
/**
2336
 * GLX_MESA_copy_sub_buffer
2337
 */
2338
#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
2339
static void
2340
__glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
2341
                       int x, int y, int width, int height)
2342
{
2343
   xGLXVendorPrivateReq *req;
2344
   struct glx_context *gc;
2345
   GLXContextTag tag;
2346
   CARD32 *drawable_ptr;
2347
   INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
2348
   CARD8 opcode;
2349
 
2350
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
2351
   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
2352
   if (pdraw != NULL) {
2353
      struct glx_screen *psc = pdraw->psc;
2354
      if (psc->driScreen->copySubBuffer != NULL) {
2355
         (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height, True);
2356
      }
2357
 
2358
      return;
2359
   }
2360
#endif
2361
 
2362
   opcode = __glXSetupForCommand(dpy);
2363
   if (!opcode)
2364
      return;
2365
 
2366
   /*
2367
    ** The calling thread may or may not have a current context.  If it
2368
    ** does, send the context tag so the server can do a flush.
2369
    */
2370
   gc = __glXGetCurrentContext();
2371
   if ((gc != NULL) && (dpy == gc->currentDpy) &&
2372
       ((drawable == gc->currentDrawable) ||
2373
        (drawable == gc->currentReadable))) {
2374
      tag = gc->currentContextTag;
2375
   }
2376
   else {
2377
      tag = 0;
2378
   }
2379
 
2380
   LockDisplay(dpy);
2381
   GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4, req);
2382
   req->reqType = opcode;
2383
   req->glxCode = X_GLXVendorPrivate;
2384
   req->vendorCode = X_GLXvop_CopySubBufferMESA;
2385
   req->contextTag = tag;
2386
 
2387
   drawable_ptr = (CARD32 *) (req + 1);
2388
   x_ptr = (INT32 *) (drawable_ptr + 1);
2389
   y_ptr = (INT32 *) (drawable_ptr + 2);
2390
   w_ptr = (INT32 *) (drawable_ptr + 3);
2391
   h_ptr = (INT32 *) (drawable_ptr + 4);
2392
 
2393
   *drawable_ptr = drawable;
2394
   *x_ptr = x;
2395
   *y_ptr = y;
2396
   *w_ptr = width;
2397
   *h_ptr = height;
2398
 
2399
   UnlockDisplay(dpy);
2400
   SyncHandle();
2401
}
2402
 
2403
/*@{*/
2404
static void
2405
__glXBindTexImageEXT(Display * dpy,
2406
                     GLXDrawable drawable, int buffer, const int *attrib_list)
2407
{
2408
   struct glx_context *gc = __glXGetCurrentContext();
2409
 
2410
   if (gc == NULL || gc->vtable->bind_tex_image == NULL)
2411
      return;
2412
 
2413
   gc->vtable->bind_tex_image(dpy, drawable, buffer, attrib_list);
2414
}
2415
 
2416
static void
2417
__glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer)
2418
{
2419
   struct glx_context *gc = __glXGetCurrentContext();
2420
 
2421
   if (gc == NULL || gc->vtable->release_tex_image == NULL)
2422
      return;
2423
 
2424
   gc->vtable->release_tex_image(dpy, drawable, buffer);
2425
}
2426
 
2427
/*@}*/
2428
 
2429
#endif /* GLX_USE_APPLEGL */
2430
 
2431
/*
2432
** glXGetProcAddress support
2433
*/
2434
 
2435
struct name_address_pair
2436
{
2437
   const char *Name;
2438
   GLvoid *Address;
2439
};
2440
 
2441
#define GLX_FUNCTION(f) { # f, (GLvoid *) f }
2442
#define GLX_FUNCTION2(n,f) { # n, (GLvoid *) f }
2443
 
2444
static const struct name_address_pair GLX_functions[] = {
2445
   /*** GLX_VERSION_1_0 ***/
2446
   GLX_FUNCTION(glXChooseVisual),
2447
   GLX_FUNCTION(glXCopyContext),
2448
   GLX_FUNCTION(glXCreateContext),
2449
   GLX_FUNCTION(glXCreateGLXPixmap),
2450
   GLX_FUNCTION(glXDestroyContext),
2451
   GLX_FUNCTION(glXDestroyGLXPixmap),
2452
   GLX_FUNCTION(glXGetConfig),
2453
   GLX_FUNCTION(glXGetCurrentContext),
2454
   GLX_FUNCTION(glXGetCurrentDrawable),
2455
   GLX_FUNCTION(glXIsDirect),
2456
   GLX_FUNCTION(glXMakeCurrent),
2457
   GLX_FUNCTION(glXQueryExtension),
2458
   GLX_FUNCTION(glXQueryVersion),
2459
   GLX_FUNCTION(glXSwapBuffers),
2460
   GLX_FUNCTION(glXUseXFont),
2461
   GLX_FUNCTION(glXWaitGL),
2462
   GLX_FUNCTION(glXWaitX),
2463
 
2464
   /*** GLX_VERSION_1_1 ***/
2465
   GLX_FUNCTION(glXGetClientString),
2466
   GLX_FUNCTION(glXQueryExtensionsString),
2467
   GLX_FUNCTION(glXQueryServerString),
2468
 
2469
   /*** GLX_VERSION_1_2 ***/
2470
   GLX_FUNCTION(glXGetCurrentDisplay),
2471
 
2472
   /*** GLX_VERSION_1_3 ***/
2473
   GLX_FUNCTION(glXChooseFBConfig),
2474
   GLX_FUNCTION(glXCreateNewContext),
2475
   GLX_FUNCTION(glXCreatePbuffer),
2476
   GLX_FUNCTION(glXCreatePixmap),
2477
   GLX_FUNCTION(glXCreateWindow),
2478
   GLX_FUNCTION(glXDestroyPbuffer),
2479
   GLX_FUNCTION(glXDestroyPixmap),
2480
   GLX_FUNCTION(glXDestroyWindow),
2481
   GLX_FUNCTION(glXGetCurrentReadDrawable),
2482
   GLX_FUNCTION(glXGetFBConfigAttrib),
2483
   GLX_FUNCTION(glXGetFBConfigs),
2484
   GLX_FUNCTION(glXGetSelectedEvent),
2485
   GLX_FUNCTION(glXGetVisualFromFBConfig),
2486
   GLX_FUNCTION(glXMakeContextCurrent),
2487
   GLX_FUNCTION(glXQueryContext),
2488
   GLX_FUNCTION(glXQueryDrawable),
2489
   GLX_FUNCTION(glXSelectEvent),
2490
 
2491
#ifndef GLX_USE_APPLEGL
2492
   /*** GLX_SGI_swap_control ***/
2493
   GLX_FUNCTION2(glXSwapIntervalSGI, __glXSwapIntervalSGI),
2494
 
2495
   /*** GLX_SGI_video_sync ***/
2496
   GLX_FUNCTION2(glXGetVideoSyncSGI, __glXGetVideoSyncSGI),
2497
   GLX_FUNCTION2(glXWaitVideoSyncSGI, __glXWaitVideoSyncSGI),
2498
 
2499
   /*** GLX_SGI_make_current_read ***/
2500
   GLX_FUNCTION2(glXMakeCurrentReadSGI, glXMakeContextCurrent),
2501
   GLX_FUNCTION2(glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable),
2502
 
2503
   /*** GLX_EXT_import_context ***/
2504
   GLX_FUNCTION(glXFreeContextEXT),
2505
   GLX_FUNCTION(glXGetContextIDEXT),
2506
   GLX_FUNCTION2(glXGetCurrentDisplayEXT, glXGetCurrentDisplay),
2507
   GLX_FUNCTION(glXImportContextEXT),
2508
   GLX_FUNCTION2(glXQueryContextInfoEXT, glXQueryContext),
2509
#endif
2510
 
2511
   /*** GLX_SGIX_fbconfig ***/
2512
   GLX_FUNCTION2(glXGetFBConfigAttribSGIX, glXGetFBConfigAttrib),
2513
   GLX_FUNCTION2(glXChooseFBConfigSGIX, glXChooseFBConfig),
2514
   GLX_FUNCTION(glXCreateGLXPixmapWithConfigSGIX),
2515
   GLX_FUNCTION(glXCreateContextWithConfigSGIX),
2516
   GLX_FUNCTION2(glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig),
2517
   GLX_FUNCTION(glXGetFBConfigFromVisualSGIX),
2518
 
2519
#ifndef GLX_USE_APPLEGL
2520
   /*** GLX_SGIX_pbuffer ***/
2521
   GLX_FUNCTION(glXCreateGLXPbufferSGIX),
2522
   GLX_FUNCTION(glXDestroyGLXPbufferSGIX),
2523
   GLX_FUNCTION(glXQueryGLXPbufferSGIX),
2524
   GLX_FUNCTION(glXSelectEventSGIX),
2525
   GLX_FUNCTION(glXGetSelectedEventSGIX),
2526
 
2527
   /*** GLX_SGIX_swap_group ***/
2528
   GLX_FUNCTION2(glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX),
2529
 
2530
   /*** GLX_SGIX_swap_barrier ***/
2531
   GLX_FUNCTION2(glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX),
2532
   GLX_FUNCTION2(glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX),
2533
 
2534
   /*** GLX_MESA_copy_sub_buffer ***/
2535
   GLX_FUNCTION2(glXCopySubBufferMESA, __glXCopySubBufferMESA),
2536
 
2537
   /*** GLX_MESA_pixmap_colormap ***/
2538
   GLX_FUNCTION(glXCreateGLXPixmapMESA),
2539
 
2540
   /*** GLX_MESA_release_buffers ***/
2541
   GLX_FUNCTION2(glXReleaseBuffersMESA, __glXReleaseBuffersMESA),
2542
 
2543
   /*** GLX_MESA_swap_control ***/
2544
   GLX_FUNCTION2(glXSwapIntervalMESA, __glXSwapIntervalMESA),
2545
   GLX_FUNCTION2(glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA),
2546
#endif
2547
 
2548
   /*** GLX_ARB_get_proc_address ***/
2549
   GLX_FUNCTION(glXGetProcAddressARB),
2550
 
2551
   /*** GLX 1.4 ***/
2552
   GLX_FUNCTION2(glXGetProcAddress, glXGetProcAddressARB),
2553
 
2554
#ifndef GLX_USE_APPLEGL
2555
   /*** GLX_OML_sync_control ***/
2556
   GLX_FUNCTION2(glXWaitForSbcOML, __glXWaitForSbcOML),
2557
   GLX_FUNCTION2(glXWaitForMscOML, __glXWaitForMscOML),
2558
   GLX_FUNCTION2(glXSwapBuffersMscOML, __glXSwapBuffersMscOML),
2559
   GLX_FUNCTION2(glXGetMscRateOML, __glXGetMscRateOML),
2560
   GLX_FUNCTION2(glXGetSyncValuesOML, __glXGetSyncValuesOML),
2561
 
2562
   /*** GLX_EXT_texture_from_pixmap ***/
2563
   GLX_FUNCTION2(glXBindTexImageEXT, __glXBindTexImageEXT),
2564
   GLX_FUNCTION2(glXReleaseTexImageEXT, __glXReleaseTexImageEXT),
2565
#endif
2566
 
2567
#if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_DRM)
2568
   /*** DRI configuration ***/
2569
   GLX_FUNCTION(glXGetScreenDriver),
2570
   GLX_FUNCTION(glXGetDriverConfig),
2571
#endif
2572
 
2573
   /*** GLX_ARB_create_context and GLX_ARB_create_context_profile ***/
2574
   GLX_FUNCTION(glXCreateContextAttribsARB),
2575
 
2576
   /*** GLX_MESA_query_renderer ***/
2577
   GLX_FUNCTION(glXQueryRendererIntegerMESA),
2578
   GLX_FUNCTION(glXQueryRendererStringMESA),
2579
   GLX_FUNCTION(glXQueryCurrentRendererIntegerMESA),
2580
   GLX_FUNCTION(glXQueryCurrentRendererStringMESA),
2581
 
2582
   {NULL, NULL}                 /* end of list */
2583
};
2584
 
2585
static const GLvoid *
2586
get_glx_proc_address(const char *funcName)
2587
{
2588
   GLuint i;
2589
 
2590
   /* try static functions */
2591
   for (i = 0; GLX_functions[i].Name; i++) {
2592
      if (strcmp(GLX_functions[i].Name, funcName) == 0)
2593
         return GLX_functions[i].Address;
2594
   }
2595
 
2596
   return NULL;
2597
}
2598
 
2599
/**
2600
 * Get the address of a named GL function.  This is the pre-GLX 1.4 name for
2601
 * \c glXGetProcAddress.
2602
 *
2603
 * \param procName  Name of a GL or GLX function.
2604
 * \returns         A pointer to the named function
2605
 *
2606
 * \sa glXGetProcAddress
2607
 */
2608
_X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
2609
{
2610
   typedef void (*gl_function) (void);
2611
   gl_function f;
2612
 
2613
 
2614
   /* Search the table of GLX and internal functions first.  If that
2615
    * fails and the supplied name could be a valid core GL name, try
2616
    * searching the core GL function table.  This check is done to prevent
2617
    * DRI based drivers from searching the core GL function table for
2618
    * internal API functions.
2619
    */
2620
   f = (gl_function) get_glx_proc_address((const char *) procName);
2621
   if ((f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
2622
       && (procName[2] != 'X')) {
2623
#ifdef GLX_SHARED_GLAPI
2624
      f = (gl_function) __indirect_get_proc_address((const char *) procName);
2625
#endif
2626
      if (!f)
2627
         f = (gl_function) _glapi_get_proc_address((const char *) procName);
2628
      if (!f) {
2629
         struct glx_context *gc = __glXGetCurrentContext();
2630
 
2631
         if (gc != NULL && gc->vtable->get_proc_address != NULL)
2632
            f = gc->vtable->get_proc_address((const char *) procName);
2633
      }
2634
   }
2635
   return f;
2636
}
2637
 
2638
/**
2639
 * Get the address of a named GL function.  This is the GLX 1.4 name for
2640
 * \c glXGetProcAddressARB.
2641
 *
2642
 * \param procName  Name of a GL or GLX function.
2643
 * \returns         A pointer to the named function
2644
 *
2645
 * \sa glXGetProcAddressARB
2646
 */
2647
_X_EXPORT void (*glXGetProcAddress(const GLubyte * procName)) (void)
2648
#if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
2649
   __attribute__ ((alias("glXGetProcAddressARB")));
2650
#else
2651
{
2652
   return glXGetProcAddressARB(procName);
2653
}
2654
#endif /* __GNUC__ */
2655
 
2656
 
2657
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
2658
/**
2659
 * Get the unadjusted system time (UST).  Currently, the UST is measured in
2660
 * microseconds since Epoc.  The actual resolution of the UST may vary from
2661
 * system to system, and the units may vary from release to release.
2662
 * Drivers should not call this function directly.  They should instead use
2663
 * \c glXGetProcAddress to obtain a pointer to the function.
2664
 *
2665
 * \param ust Location to store the 64-bit UST
2666
 * \returns Zero on success or a negative errno value on failure.
2667
 *
2668
 * \sa glXGetProcAddress, PFNGLXGETUSTPROC
2669
 *
2670
 * \since Internal API version 20030317.
2671
 */
2672
_X_HIDDEN int
2673
__glXGetUST(int64_t * ust)
2674
{
2675
   struct timeval tv;
2676
 
2677
   if (ust == NULL) {
2678
      return -EFAULT;
2679
   }
2680
 
2681
   if (gettimeofday(&tv, NULL) == 0) {
2682
      ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
2683
      return 0;
2684
   }
2685
   else {
2686
      return -errno;
2687
   }
2688
}
2689
#endif /* GLX_DIRECT_RENDERING */