glxcmds.c revision edb5253dfa0751e451dca7c9a494be4609390545
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 "glcontextmodes.h"
40
41#ifdef GLX_DIRECT_RENDERING
42#include <sys/time.h>
43#include <X11/extensions/xf86vmode.h>
44#include "xf86dri.h"
45#define GC_IS_DIRECT(gc) ((gc)->driContext != NULL)
46#else
47#define GC_IS_DIRECT(gc) (0)
48#endif
49
50#if defined(USE_XCB)
51#include <X11/Xlib-xcb.h>
52#include <xcb/xcb.h>
53#include <xcb/glx.h>
54#endif
55
56static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
57static const char __glXGLXClientVersion[] = "1.4";
58
59
60/****************************************************************************/
61
62#ifdef GLX_DIRECT_RENDERING
63
64static Bool windowExistsFlag;
65static int
66windowExistsErrorHandler(Display * dpy, XErrorEvent * xerr)
67{
68   (void) dpy;
69
70   if (xerr->error_code == BadWindow) {
71      windowExistsFlag = GL_FALSE;
72   }
73   return 0;
74}
75
76/**
77 * Find drawables in the local hash that have been destroyed on the
78 * server.
79 *
80 * \param dpy    Display to destroy drawables for
81 * \param screen Screen number to destroy drawables for
82 */
83static void
84GarbageCollectDRIDrawables(Display * dpy, __GLXscreenConfigs * sc)
85{
86   XID draw;
87   __GLXDRIdrawable *pdraw;
88   XWindowAttributes xwa;
89   int (*oldXErrorHandler) (Display *, XErrorEvent *);
90
91   /* Set no-op error handler so Xlib doesn't bail out if the windows
92    * has alreay been destroyed on the server. */
93   XSync(dpy, GL_FALSE);
94   oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
95
96   if (__glxHashFirst(sc->drawHash, &draw, (void *) &pdraw) == 1) {
97      do {
98         windowExistsFlag = GL_TRUE;
99         XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
100         if (!windowExistsFlag) {
101            /* Destroy the local drawable data, if the drawable no
102               longer exists in the Xserver */
103            (*pdraw->destroyDrawable) (pdraw);
104            __glxHashDelete(sc->drawHash, draw);
105         }
106      } while (__glxHashNext(sc->drawHash, &draw, (void *) &pdraw) == 1);
107   }
108
109   XSync(dpy, GL_FALSE);
110   XSetErrorHandler(oldXErrorHandler);
111}
112
113/**
114 * Get the __DRIdrawable for the drawable associated with a GLXContext
115 *
116 * \param dpy       The display associated with \c drawable.
117 * \param drawable  GLXDrawable whose __DRIdrawable part is to be retrieved.
118 * \param scrn_num  If non-NULL, the drawables screen is stored there
119 * \returns  A pointer to the context's __DRIdrawable on success, or NULL if
120 *           the drawable is not associated with a direct-rendering context.
121 */
122_X_HIDDEN __GLXDRIdrawable *
123GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable, int *const scrn_num)
124{
125   __GLXdisplayPrivate *priv = __glXInitialize(dpy);
126   __GLXDRIdrawable *pdraw;
127   const unsigned screen_count = ScreenCount(dpy);
128   unsigned i;
129   __GLXscreenConfigs *psc;
130
131   if (priv == NULL)
132      return NULL;
133
134   for (i = 0; i < screen_count; i++) {
135      psc = &priv->screenConfigs[i];
136      if (psc->drawHash == NULL)
137         continue;
138
139      if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) {
140         if (scrn_num != NULL)
141            *scrn_num = i;
142         return pdraw;
143      }
144   }
145
146   return NULL;
147}
148
149#endif
150
151
152/**
153 * Get the GLX per-screen data structure associated with a GLX context.
154 *
155 * \param dpy   Display for which the GLX per-screen information is to be
156 *              retrieved.
157 * \param scrn  Screen on \c dpy for which the GLX per-screen information is
158 *              to be retrieved.
159 * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn
160 *          specify a valid GLX screen, or NULL otherwise.
161 *
162 * \todo Should this function validate that \c scrn is within the screen
163 *       number range for \c dpy?
164 */
165
166static __GLXscreenConfigs *
167GetGLXScreenConfigs(Display * dpy, int scrn)
168{
169   __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
170
171   return (priv
172           && priv->screenConfigs !=
173           NULL) ? &priv->screenConfigs[scrn] : NULL;
174}
175
176
177static int
178GetGLXPrivScreenConfig(Display * dpy, int scrn, __GLXdisplayPrivate ** ppriv,
179                       __GLXscreenConfigs ** ppsc)
180{
181   /* Initialize the extension, if needed .  This has the added value
182    * of initializing/allocating the display private
183    */
184
185   if (dpy == NULL) {
186      return GLX_NO_EXTENSION;
187   }
188
189   *ppriv = __glXInitialize(dpy);
190   if (*ppriv == NULL) {
191      return GLX_NO_EXTENSION;
192   }
193
194   /* Check screen number to see if its valid */
195   if ((scrn < 0) || (scrn >= ScreenCount(dpy))) {
196      return GLX_BAD_SCREEN;
197   }
198
199   /* Check to see if the GL is supported on this screen */
200   *ppsc = &((*ppriv)->screenConfigs[scrn]);
201   if ((*ppsc)->configs == NULL) {
202      /* No support for GL on this screen regardless of visual */
203      return GLX_BAD_VISUAL;
204   }
205
206   return Success;
207}
208
209
210/**
211 * Determine if a \c GLXFBConfig supplied by the application is valid.
212 *
213 * \param dpy     Application supplied \c Display pointer.
214 * \param config  Application supplied \c GLXFBConfig.
215 *
216 * \returns If the \c GLXFBConfig is valid, the a pointer to the matching
217 *          \c __GLcontextModes structure is returned.  Otherwise, \c NULL
218 *          is returned.
219 */
220static __GLcontextModes *
221ValidateGLXFBConfig(Display * dpy, GLXFBConfig config)
222{
223   __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
224   const unsigned num_screens = ScreenCount(dpy);
225   unsigned i;
226   const __GLcontextModes *modes;
227
228
229   if (priv != NULL) {
230      for (i = 0; i < num_screens; i++) {
231         for (modes = priv->screenConfigs[i].configs; modes != NULL;
232              modes = modes->next) {
233            if (modes == (__GLcontextModes *) config) {
234               return (__GLcontextModes *) config;
235            }
236         }
237      }
238   }
239
240   return NULL;
241}
242
243
244/**
245 * \todo It should be possible to move the allocate of \c client_state_private
246 * later in the function for direct-rendering contexts.  Direct-rendering
247 * contexts don't need to track client state, so they don't need that memory
248 * at all.
249 *
250 * \todo Eliminate \c __glXInitVertexArrayState.  Replace it with a new
251 * function called \c __glXAllocateClientState that allocates the memory and
252 * does all the initialization (including the pixel pack / unpack).
253 */
254static GLXContext
255AllocateGLXContext(Display * dpy)
256{
257   GLXContext gc;
258   int bufSize;
259   CARD8 opcode;
260   __GLXattribute *state;
261
262   if (!dpy)
263      return NULL;
264
265   opcode = __glXSetupForCommand(dpy);
266   if (!opcode) {
267      return NULL;
268   }
269
270   /* Allocate our context record */
271   gc = (GLXContext) Xmalloc(sizeof(struct __GLXcontextRec));
272   if (!gc) {
273      /* Out of memory */
274      return NULL;
275   }
276   memset(gc, 0, sizeof(struct __GLXcontextRec));
277
278   state = Xmalloc(sizeof(struct __GLXattributeRec));
279   if (state == NULL) {
280      /* Out of memory */
281      Xfree(gc);
282      return NULL;
283   }
284   gc->client_state_private = state;
285   memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec));
286   state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
287
288   /*
289    ** Create a temporary buffer to hold GLX rendering commands.  The size
290    ** of the buffer is selected so that the maximum number of GLX rendering
291    ** commands can fit in a single X packet and still have room in the X
292    ** packet for the GLXRenderReq header.
293    */
294
295   bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq;
296   gc->buf = (GLubyte *) Xmalloc(bufSize);
297   if (!gc->buf) {
298      Xfree(gc->client_state_private);
299      Xfree(gc);
300      return NULL;
301   }
302   gc->bufSize = bufSize;
303
304   /* Fill in the new context */
305   gc->renderMode = GL_RENDER;
306
307   state->storePack.alignment = 4;
308   state->storeUnpack.alignment = 4;
309
310   gc->attributes.stackPointer = &gc->attributes.stack[0];
311
312   /*
313    ** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
314    ** Other code uses the fastImageUnpack bit, but it is never set
315    ** to GL_TRUE.
316    */
317   gc->fastImageUnpack = GL_FALSE;
318   gc->fillImage = __glFillImage;
319   gc->pc = gc->buf;
320   gc->bufEnd = gc->buf + bufSize;
321   gc->isDirect = GL_FALSE;
322   if (__glXDebug) {
323      /*
324       ** Set limit register so that there will be one command per packet
325       */
326      gc->limit = gc->buf;
327   }
328   else {
329      gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
330   }
331   gc->createDpy = dpy;
332   gc->majorOpcode = opcode;
333
334   /*
335    ** Constrain the maximum drawing command size allowed to be
336    ** transfered using the X_GLXRender protocol request.  First
337    ** constrain by a software limit, then constrain by the protocl
338    ** limit.
339    */
340   if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
341      bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
342   }
343   if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
344      bufSize = __GLX_MAX_RENDER_CMD_SIZE;
345   }
346   gc->maxSmallRenderCommandSize = bufSize;
347   return gc;
348}
349
350
351/**
352 * Create a new context.  Exactly one of \c vis and \c fbconfig should be
353 * non-NULL.
354 *
355 * \param use_glx_1_3  For FBConfigs, should GLX 1.3 protocol or
356 *                     SGIX_fbconfig protocol be used?
357 * \param renderType   For FBConfigs, what is the rendering type?
358 */
359
360static GLXContext
361CreateContext(Display * dpy, int generic_id,
362              const __GLcontextModes * const fbconfig,
363              GLXContext shareList,
364              Bool allowDirect,
365	      unsigned code, int renderType, int screen)
366{
367   GLXContext gc;
368#ifdef GLX_DIRECT_RENDERING
369   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
370#endif
371
372   if (dpy == NULL)
373      return NULL;
374
375   if (generic_id == None)
376      return NULL;
377
378   gc = AllocateGLXContext(dpy);
379   if (!gc)
380      return NULL;
381
382#ifdef GLX_DIRECT_RENDERING
383   if (allowDirect && psc->driScreen) {
384      gc->driContext = psc->driScreen->createContext(psc, fbconfig, gc,
385						     shareList, renderType);
386      if (gc->driContext != NULL) {
387	 gc->screen = screen;
388	 gc->psc = psc;
389	 gc->mode = fbconfig;
390	 gc->isDirect = GL_TRUE;
391      }
392   }
393#endif
394
395   LockDisplay(dpy);
396   switch (code) {
397   case X_GLXCreateContext: {
398      xGLXCreateContextReq *req;
399
400      /* Send the glXCreateContext request */
401      GetReq(GLXCreateContext, req);
402      req->reqType = gc->majorOpcode;
403      req->glxCode = X_GLXCreateContext;
404      req->context = gc->xid = XAllocID(dpy);
405      req->visual = generic_id;
406      req->screen = screen;
407      req->shareList = shareList ? shareList->xid : None;
408      req->isDirect = GC_IS_DIRECT(gc);
409      break;
410   }
411
412   case X_GLXCreateNewContext: {
413      xGLXCreateNewContextReq *req;
414
415      /* Send the glXCreateNewContext request */
416      GetReq(GLXCreateNewContext, req);
417      req->reqType = gc->majorOpcode;
418      req->glxCode = X_GLXCreateNewContext;
419      req->context = gc->xid = XAllocID(dpy);
420      req->fbconfig = generic_id;
421      req->screen = screen;
422      req->renderType = renderType;
423      req->shareList = shareList ? shareList->xid : None;
424      req->isDirect = GC_IS_DIRECT(gc);
425      break;
426   }
427
428   case X_GLXvop_CreateContextWithConfigSGIX: {
429      xGLXVendorPrivateWithReplyReq *vpreq;
430      xGLXCreateContextWithConfigSGIXReq *req;
431
432      /* Send the glXCreateNewContext request */
433      GetReqExtra(GLXVendorPrivateWithReply,
434		  sz_xGLXCreateContextWithConfigSGIXReq -
435		  sz_xGLXVendorPrivateWithReplyReq, vpreq);
436      req = (xGLXCreateContextWithConfigSGIXReq *) vpreq;
437      req->reqType = gc->majorOpcode;
438      req->glxCode = X_GLXVendorPrivateWithReply;
439      req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
440      req->context = gc->xid = XAllocID(dpy);
441      req->fbconfig = generic_id;
442      req->screen = screen;
443      req->renderType = renderType;
444      req->shareList = shareList ? shareList->xid : None;
445      req->isDirect = GC_IS_DIRECT(gc);
446      break;
447   }
448
449   default:
450      /* What to do here?  This case is the sign of an internal error.  It
451       * should never be reachable.
452       */
453      break;
454   }
455
456   UnlockDisplay(dpy);
457   SyncHandle();
458
459   gc->imported = GL_FALSE;
460   gc->renderType = renderType;
461
462   return gc;
463}
464
465PUBLIC GLXContext
466glXCreateContext(Display * dpy, XVisualInfo * vis,
467                 GLXContext shareList, Bool allowDirect)
468{
469   const __GLcontextModes *mode = NULL;
470   int renderType = 0;
471
472#ifdef GLX_DIRECT_RENDERING
473   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, vis->screen);
474
475   mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
476   if (mode == NULL) {
477      xError error;
478
479      error.errorCode = BadValue;
480      error.resourceID = vis->visualid;
481      error.sequenceNumber = dpy->request;
482      error.type = X_Error;
483      error.majorCode = __glXSetupForCommand(dpy);
484      error.minorCode = X_GLXCreateContext;
485      _XError(dpy, &error);
486      return None;
487   }
488
489   renderType = mode->rgbMode ? GLX_RGBA_TYPE : GLX_COLOR_INDEX_TYPE;
490#endif
491
492   return CreateContext(dpy, vis->visualid, mode, shareList, allowDirect,
493                        X_GLXCreateContext, renderType, vis->screen);
494}
495
496_X_HIDDEN void
497__glXFreeContext(__GLXcontext * gc)
498{
499   if (gc->vendor)
500      XFree((char *) gc->vendor);
501   if (gc->renderer)
502      XFree((char *) gc->renderer);
503   if (gc->version)
504      XFree((char *) gc->version);
505   if (gc->extensions)
506      XFree((char *) gc->extensions);
507   __glFreeAttributeState(gc);
508   XFree((char *) gc->buf);
509   Xfree((char *) gc->client_state_private);
510   XFree((char *) gc);
511
512}
513
514/*
515** Destroy the named context
516*/
517static void
518DestroyContext(Display * dpy, GLXContext gc)
519{
520   xGLXDestroyContextReq *req;
521   GLXContextID xid;
522   CARD8 opcode;
523   GLboolean imported;
524
525   opcode = __glXSetupForCommand(dpy);
526   if (!opcode || !gc) {
527      return;
528   }
529
530   __glXLock();
531   xid = gc->xid;
532   imported = gc->imported;
533   gc->xid = None;
534
535   if (gc->currentDpy) {
536      /* This context is bound to some thread.  According to the man page,
537       * we should not actually delete the context until it's unbound.
538       * Note that we set gc->xid = None above.  In MakeContextCurrent()
539       * we check for that and delete the context there.
540       */
541      __glXUnlock();
542      return;
543   }
544
545#ifdef GLX_DIRECT_RENDERING
546   /* Destroy the direct rendering context */
547   if (gc->driContext) {
548      (*gc->driContext->destroyContext) (gc->driContext, gc->psc, dpy);
549      gc->driContext = NULL;
550      GarbageCollectDRIDrawables(dpy, gc->psc);
551   }
552#endif
553
554   __glXFreeVertexArrayState(gc);
555
556   if (gc->currentDpy) {
557      /* Have to free later cuz it's in use now */
558      __glXUnlock();
559   }
560   else {
561      /* Destroy the handle if not current to anybody */
562      __glXUnlock();
563      __glXFreeContext(gc);
564   }
565
566   if (!imported) {
567      /*
568       ** This dpy also created the server side part of the context.
569       ** Send the glXDestroyContext request.
570       */
571      LockDisplay(dpy);
572      GetReq(GLXDestroyContext, req);
573      req->reqType = opcode;
574      req->glxCode = X_GLXDestroyContext;
575      req->context = xid;
576      UnlockDisplay(dpy);
577      SyncHandle();
578   }
579}
580
581PUBLIC void
582glXDestroyContext(Display * dpy, GLXContext gc)
583{
584   DestroyContext(dpy, gc);
585}
586
587/*
588** Return the major and minor version #s for the GLX extension
589*/
590PUBLIC Bool
591glXQueryVersion(Display * dpy, int *major, int *minor)
592{
593   __GLXdisplayPrivate *priv;
594
595   /* Init the extension.  This fetches the major and minor version. */
596   priv = __glXInitialize(dpy);
597   if (!priv)
598      return GL_FALSE;
599
600   if (major)
601      *major = priv->majorVersion;
602   if (minor)
603      *minor = priv->minorVersion;
604   return GL_TRUE;
605}
606
607/*
608** Query the existance of the GLX extension
609*/
610PUBLIC Bool
611glXQueryExtension(Display * dpy, int *errorBase, int *eventBase)
612{
613   int major_op, erb, evb;
614   Bool rv;
615
616   rv = XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_op, &evb, &erb);
617   if (rv) {
618      if (errorBase)
619         *errorBase = erb;
620      if (eventBase)
621         *eventBase = evb;
622   }
623   return rv;
624}
625
626/*
627** Put a barrier in the token stream that forces the GL to finish its
628** work before X can proceed.
629*/
630PUBLIC void
631glXWaitGL(void)
632{
633   xGLXWaitGLReq *req;
634   GLXContext gc = __glXGetCurrentContext();
635   Display *dpy = gc->currentDpy;
636
637   if (!dpy)
638      return;
639
640   /* Flush any pending commands out */
641   __glXFlushRenderBuffer(gc, gc->pc);
642
643#ifdef GLX_DIRECT_RENDERING
644   if (gc->driContext) {
645      int screen;
646      __GLXDRIdrawable *pdraw =
647         GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
648
649      if (pdraw != NULL) {
650         __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
651         glFlush();
652         if (psc->driScreen->waitGL != NULL)
653            (*psc->driScreen->waitGL) (pdraw);
654      }
655      return;
656   }
657#endif
658
659   /* Send the glXWaitGL request */
660   LockDisplay(dpy);
661   GetReq(GLXWaitGL, req);
662   req->reqType = gc->majorOpcode;
663   req->glxCode = X_GLXWaitGL;
664   req->contextTag = gc->currentContextTag;
665   UnlockDisplay(dpy);
666   SyncHandle();
667}
668
669/*
670** Put a barrier in the token stream that forces X to finish its
671** work before GL can proceed.
672*/
673PUBLIC void
674glXWaitX(void)
675{
676   xGLXWaitXReq *req;
677   GLXContext gc = __glXGetCurrentContext();
678   Display *dpy = gc->currentDpy;
679
680   if (!dpy)
681      return;
682
683   /* Flush any pending commands out */
684   __glXFlushRenderBuffer(gc, gc->pc);
685
686#ifdef GLX_DIRECT_RENDERING
687   if (gc->driContext) {
688      int screen;
689      __GLXDRIdrawable *pdraw =
690         GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
691
692      if (pdraw != NULL) {
693         __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
694         if (psc->driScreen->waitX != NULL)
695            (*psc->driScreen->waitX) (pdraw);
696      }
697      else
698         XSync(dpy, False);
699      return;
700   }
701#endif
702
703   /*
704    ** Send the glXWaitX request.
705    */
706   LockDisplay(dpy);
707   GetReq(GLXWaitX, req);
708   req->reqType = gc->majorOpcode;
709   req->glxCode = X_GLXWaitX;
710   req->contextTag = gc->currentContextTag;
711   UnlockDisplay(dpy);
712   SyncHandle();
713}
714
715PUBLIC void
716glXUseXFont(Font font, int first, int count, int listBase)
717{
718   xGLXUseXFontReq *req;
719   GLXContext gc = __glXGetCurrentContext();
720   Display *dpy = gc->currentDpy;
721
722   if (!dpy)
723      return;
724
725   /* Flush any pending commands out */
726   (void) __glXFlushRenderBuffer(gc, gc->pc);
727
728#ifdef GLX_DIRECT_RENDERING
729   if (gc->driContext) {
730      DRI_glXUseXFont(font, first, count, listBase);
731      return;
732   }
733#endif
734
735   /* Send the glXUseFont request */
736   LockDisplay(dpy);
737   GetReq(GLXUseXFont, req);
738   req->reqType = gc->majorOpcode;
739   req->glxCode = X_GLXUseXFont;
740   req->contextTag = gc->currentContextTag;
741   req->font = font;
742   req->first = first;
743   req->count = count;
744   req->listBase = listBase;
745   UnlockDisplay(dpy);
746   SyncHandle();
747}
748
749/************************************************************************/
750
751/*
752** Copy the source context to the destination context using the
753** attribute "mask".
754*/
755PUBLIC void
756glXCopyContext(Display * dpy, GLXContext source,
757               GLXContext dest, unsigned long mask)
758{
759   xGLXCopyContextReq *req;
760   GLXContext gc = __glXGetCurrentContext();
761   GLXContextTag tag;
762   CARD8 opcode;
763
764   opcode = __glXSetupForCommand(dpy);
765   if (!opcode) {
766      return;
767   }
768
769#ifdef GLX_DIRECT_RENDERING
770   if (gc->driContext) {
771      /* NOT_DONE: This does not work yet */
772   }
773#endif
774
775   /*
776    ** If the source is the current context, send its tag so that the context
777    ** can be flushed before the copy.
778    */
779   if (source == gc && dpy == gc->currentDpy) {
780      tag = gc->currentContextTag;
781   }
782   else {
783      tag = 0;
784   }
785
786   /* Send the glXCopyContext request */
787   LockDisplay(dpy);
788   GetReq(GLXCopyContext, req);
789   req->reqType = opcode;
790   req->glxCode = X_GLXCopyContext;
791   req->source = source ? source->xid : None;
792   req->dest = dest ? dest->xid : None;
793   req->mask = mask;
794   req->contextTag = tag;
795   UnlockDisplay(dpy);
796   SyncHandle();
797}
798
799
800/**
801 * Determine if a context uses direct rendering.
802 *
803 * \param dpy        Display where the context was created.
804 * \param contextID  ID of the context to be tested.
805 *
806 * \returns \c GL_TRUE if the context is direct rendering or not.
807 */
808static Bool
809__glXIsDirect(Display * dpy, GLXContextID contextID)
810{
811#if !defined(USE_XCB)
812   xGLXIsDirectReq *req;
813   xGLXIsDirectReply reply;
814#endif
815   CARD8 opcode;
816
817   opcode = __glXSetupForCommand(dpy);
818   if (!opcode) {
819      return GL_FALSE;
820   }
821
822#ifdef USE_XCB
823   xcb_connection_t *c = XGetXCBConnection(dpy);
824   xcb_glx_is_direct_reply_t *reply = xcb_glx_is_direct_reply(c,
825                                                              xcb_glx_is_direct
826                                                              (c, contextID),
827                                                              NULL);
828
829   const Bool is_direct = reply->is_direct ? True : False;
830   free(reply);
831
832   return is_direct;
833#else
834   /* Send the glXIsDirect request */
835   LockDisplay(dpy);
836   GetReq(GLXIsDirect, req);
837   req->reqType = opcode;
838   req->glxCode = X_GLXIsDirect;
839   req->context = contextID;
840   _XReply(dpy, (xReply *) & reply, 0, False);
841   UnlockDisplay(dpy);
842   SyncHandle();
843
844   return reply.isDirect;
845#endif /* USE_XCB */
846}
847
848/**
849 * \todo
850 * Shouldn't this function \b always return \c GL_FALSE when
851 * \c GLX_DIRECT_RENDERING is not defined?  Do we really need to bother with
852 * the GLX protocol here at all?
853 */
854PUBLIC Bool
855glXIsDirect(Display * dpy, GLXContext gc)
856{
857   if (!gc) {
858      return GL_FALSE;
859   }
860   else if (GC_IS_DIRECT(gc)) {
861      return GL_TRUE;
862   }
863   return __glXIsDirect(dpy, gc->xid);
864}
865
866PUBLIC GLXPixmap
867glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
868{
869   xGLXCreateGLXPixmapReq *req;
870   GLXPixmap xid;
871   CARD8 opcode;
872
873   opcode = __glXSetupForCommand(dpy);
874   if (!opcode) {
875      return None;
876   }
877
878   /* Send the glXCreateGLXPixmap request */
879   LockDisplay(dpy);
880   GetReq(GLXCreateGLXPixmap, req);
881   req->reqType = opcode;
882   req->glxCode = X_GLXCreateGLXPixmap;
883   req->screen = vis->screen;
884   req->visual = vis->visualid;
885   req->pixmap = pixmap;
886   req->glxpixmap = xid = XAllocID(dpy);
887   UnlockDisplay(dpy);
888   SyncHandle();
889
890#ifdef GLX_DIRECT_RENDERING
891   do {
892      /* FIXME: Maybe delay __DRIdrawable creation until the drawable
893       * is actually bound to a context... */
894
895      __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
896      __GLXDRIdrawable *pdraw;
897      __GLXscreenConfigs *psc;
898      __GLcontextModes *modes;
899
900      psc = &priv->screenConfigs[vis->screen];
901      if (psc->driScreen == NULL)
902         break;
903      modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
904      pdraw = psc->driScreen->createDrawable(psc, pixmap, req->glxpixmap, modes);
905      if (pdraw == NULL) {
906         fprintf(stderr, "failed to create pixmap\n");
907         break;
908      }
909
910      if (__glxHashInsert(psc->drawHash, req->glxpixmap, pdraw)) {
911         (*pdraw->destroyDrawable) (pdraw);
912         return None;           /* FIXME: Check what we're supposed to do here... */
913      }
914   } while (0);
915#endif
916
917   return xid;
918}
919
920/*
921** Destroy the named pixmap
922*/
923PUBLIC void
924glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
925{
926   xGLXDestroyGLXPixmapReq *req;
927   CARD8 opcode;
928
929   opcode = __glXSetupForCommand(dpy);
930   if (!opcode) {
931      return;
932   }
933
934   /* Send the glXDestroyGLXPixmap request */
935   LockDisplay(dpy);
936   GetReq(GLXDestroyGLXPixmap, req);
937   req->reqType = opcode;
938   req->glxCode = X_GLXDestroyGLXPixmap;
939   req->glxpixmap = glxpixmap;
940   UnlockDisplay(dpy);
941   SyncHandle();
942
943#ifdef GLX_DIRECT_RENDERING
944   {
945      int screen;
946      __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
947      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap, &screen);
948      __GLXscreenConfigs *psc = &priv->screenConfigs[screen];
949
950      if (pdraw != NULL) {
951         (*pdraw->destroyDrawable) (pdraw);
952         __glxHashDelete(psc->drawHash, glxpixmap);
953      }
954   }
955#endif
956}
957
958PUBLIC void
959glXSwapBuffers(Display * dpy, GLXDrawable drawable)
960{
961   GLXContext gc;
962   GLXContextTag tag;
963   CARD8 opcode;
964#ifdef USE_XCB
965   xcb_connection_t *c;
966#else
967   xGLXSwapBuffersReq *req;
968#endif
969
970#ifdef GLX_DIRECT_RENDERING
971   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
972
973   if (pdraw != NULL) {
974      glFlush();
975      (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0);
976      return;
977   }
978#endif
979
980   opcode = __glXSetupForCommand(dpy);
981   if (!opcode) {
982      return;
983   }
984
985   /*
986    ** The calling thread may or may not have a current context.  If it
987    ** does, send the context tag so the server can do a flush.
988    */
989   gc = __glXGetCurrentContext();
990   if ((gc != NULL) && (dpy == gc->currentDpy) &&
991       ((drawable == gc->currentDrawable)
992        || (drawable == gc->currentReadable))) {
993      tag = gc->currentContextTag;
994   }
995   else {
996      tag = 0;
997   }
998
999#ifdef USE_XCB
1000   c = XGetXCBConnection(dpy);
1001   xcb_glx_swap_buffers(c, tag, drawable);
1002   xcb_flush(c);
1003#else
1004   /* Send the glXSwapBuffers request */
1005   LockDisplay(dpy);
1006   GetReq(GLXSwapBuffers, req);
1007   req->reqType = opcode;
1008   req->glxCode = X_GLXSwapBuffers;
1009   req->drawable = drawable;
1010   req->contextTag = tag;
1011   UnlockDisplay(dpy);
1012   SyncHandle();
1013   XFlush(dpy);
1014#endif /* USE_XCB */
1015}
1016
1017
1018/*
1019** Return configuration information for the given display, screen and
1020** visual combination.
1021*/
1022PUBLIC int
1023glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute,
1024             int *value_return)
1025{
1026   __GLXdisplayPrivate *priv;
1027   __GLXscreenConfigs *psc;
1028   __GLcontextModes *modes;
1029   int status;
1030
1031   status = GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc);
1032   if (status == Success) {
1033      modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
1034
1035      /* Lookup attribute after first finding a match on the visual */
1036      if (modes != NULL) {
1037         return _gl_get_context_mode_data(modes, attribute, value_return);
1038      }
1039
1040      status = GLX_BAD_VISUAL;
1041   }
1042
1043   /*
1044    ** If we can't find the config for this visual, this visual is not
1045    ** supported by the OpenGL implementation on the server.
1046    */
1047   if ((status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL)) {
1048      *value_return = GL_FALSE;
1049      status = Success;
1050   }
1051
1052   return status;
1053}
1054
1055/************************************************************************/
1056
1057static void
1058init_fbconfig_for_chooser(__GLcontextModes * config,
1059                          GLboolean fbconfig_style_tags)
1060{
1061   memset(config, 0, sizeof(__GLcontextModes));
1062   config->visualID = (XID) GLX_DONT_CARE;
1063   config->visualType = GLX_DONT_CARE;
1064
1065   /* glXChooseFBConfig specifies different defaults for these two than
1066    * glXChooseVisual.
1067    */
1068   if (fbconfig_style_tags) {
1069      config->rgbMode = GL_TRUE;
1070      config->doubleBufferMode = GLX_DONT_CARE;
1071   }
1072
1073   config->visualRating = GLX_DONT_CARE;
1074   config->transparentPixel = GLX_NONE;
1075   config->transparentRed = GLX_DONT_CARE;
1076   config->transparentGreen = GLX_DONT_CARE;
1077   config->transparentBlue = GLX_DONT_CARE;
1078   config->transparentAlpha = GLX_DONT_CARE;
1079   config->transparentIndex = GLX_DONT_CARE;
1080
1081   config->drawableType = GLX_WINDOW_BIT;
1082   config->renderType =
1083      (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
1084   config->xRenderable = GLX_DONT_CARE;
1085   config->fbconfigID = (GLXFBConfigID) (GLX_DONT_CARE);
1086
1087   config->swapMethod = GLX_DONT_CARE;
1088}
1089
1090#define MATCH_DONT_CARE( param )        \
1091  do {                                  \
1092    if ( ((int) a-> param != (int) GLX_DONT_CARE)   \
1093         && (a-> param != b-> param) ) {        \
1094      return False;                             \
1095    }                                           \
1096  } while ( 0 )
1097
1098#define MATCH_MINIMUM( param )                  \
1099  do {                                          \
1100    if ( ((int) a-> param != (int) GLX_DONT_CARE)	\
1101         && (a-> param > b-> param) ) {         \
1102      return False;                             \
1103    }                                           \
1104  } while ( 0 )
1105
1106#define MATCH_EXACT( param )                    \
1107  do {                                          \
1108    if ( a-> param != b-> param) {              \
1109      return False;                             \
1110    }                                           \
1111  } while ( 0 )
1112
1113/* Test that all bits from a are contained in b */
1114#define MATCH_MASK(param)			\
1115  do {						\
1116    if ((a->param & ~b->param) != 0)		\
1117      return False;				\
1118  } while (0);
1119
1120/**
1121 * Determine if two GLXFBConfigs are compatible.
1122 *
1123 * \param a  Application specified config to test.
1124 * \param b  Server specified config to test against \c a.
1125 */
1126static Bool
1127fbconfigs_compatible(const __GLcontextModes * const a,
1128                     const __GLcontextModes * const b)
1129{
1130   MATCH_DONT_CARE(doubleBufferMode);
1131   MATCH_DONT_CARE(visualType);
1132   MATCH_DONT_CARE(visualRating);
1133   MATCH_DONT_CARE(xRenderable);
1134   MATCH_DONT_CARE(fbconfigID);
1135   MATCH_DONT_CARE(swapMethod);
1136
1137   MATCH_MINIMUM(rgbBits);
1138   MATCH_MINIMUM(numAuxBuffers);
1139   MATCH_MINIMUM(redBits);
1140   MATCH_MINIMUM(greenBits);
1141   MATCH_MINIMUM(blueBits);
1142   MATCH_MINIMUM(alphaBits);
1143   MATCH_MINIMUM(depthBits);
1144   MATCH_MINIMUM(stencilBits);
1145   MATCH_MINIMUM(accumRedBits);
1146   MATCH_MINIMUM(accumGreenBits);
1147   MATCH_MINIMUM(accumBlueBits);
1148   MATCH_MINIMUM(accumAlphaBits);
1149   MATCH_MINIMUM(sampleBuffers);
1150   MATCH_MINIMUM(maxPbufferWidth);
1151   MATCH_MINIMUM(maxPbufferHeight);
1152   MATCH_MINIMUM(maxPbufferPixels);
1153   MATCH_MINIMUM(samples);
1154
1155   MATCH_DONT_CARE(stereoMode);
1156   MATCH_EXACT(level);
1157
1158   MATCH_MASK(drawableType);
1159   MATCH_MASK(renderType);
1160
1161   /* There is a bug in a few of the XFree86 DDX drivers.  They contain
1162    * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
1163    * Technically speaking, it is a bug in the DDX driver, but there is
1164    * enough of an installed base to work around the problem here.  In any
1165    * case, 0 is not a valid value of the transparent type, so we'll treat 0
1166    * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
1167    * 0 from the server to be a match to maintain backward compatibility with
1168    * the (broken) drivers.
1169    */
1170
1171   if (a->transparentPixel != (int) GLX_DONT_CARE && a->transparentPixel != 0) {
1172      if (a->transparentPixel == GLX_NONE) {
1173         if (b->transparentPixel != GLX_NONE && b->transparentPixel != 0)
1174            return False;
1175      }
1176      else {
1177         MATCH_EXACT(transparentPixel);
1178      }
1179
1180      switch (a->transparentPixel) {
1181      case GLX_TRANSPARENT_RGB:
1182         MATCH_DONT_CARE(transparentRed);
1183         MATCH_DONT_CARE(transparentGreen);
1184         MATCH_DONT_CARE(transparentBlue);
1185         MATCH_DONT_CARE(transparentAlpha);
1186         break;
1187
1188      case GLX_TRANSPARENT_INDEX:
1189         MATCH_DONT_CARE(transparentIndex);
1190         break;
1191
1192      default:
1193         break;
1194      }
1195   }
1196
1197   return True;
1198}
1199
1200
1201/* There's some trickly language in the GLX spec about how this is supposed
1202 * to work.  Basically, if a given component size is either not specified
1203 * or the requested size is zero, it is supposed to act like PERFER_SMALLER.
1204 * Well, that's really hard to do with the code as-is.  This behavior is
1205 * closer to correct, but still not technically right.
1206 */
1207#define PREFER_LARGER_OR_ZERO(comp)             \
1208  do {                                          \
1209    if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
1210      if ( ((*a)-> comp) == 0 ) {               \
1211        return -1;                              \
1212      }                                         \
1213      else if ( ((*b)-> comp) == 0 ) {          \
1214        return 1;                               \
1215      }                                         \
1216      else {                                    \
1217        return ((*b)-> comp) - ((*a)-> comp) ;  \
1218      }                                         \
1219    }                                           \
1220  } while( 0 )
1221
1222#define PREFER_LARGER(comp)                     \
1223  do {                                          \
1224    if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
1225      return ((*b)-> comp) - ((*a)-> comp) ;    \
1226    }                                           \
1227  } while( 0 )
1228
1229#define PREFER_SMALLER(comp)                    \
1230  do {                                          \
1231    if ( ((*a)-> comp) != ((*b)-> comp) ) {     \
1232      return ((*a)-> comp) - ((*b)-> comp) ;    \
1233    }                                           \
1234  } while( 0 )
1235
1236/**
1237 * Compare two GLXFBConfigs.  This function is intended to be used as the
1238 * compare function passed in to qsort.
1239 *
1240 * \returns If \c a is a "better" config, according to the specification of
1241 *          SGIX_fbconfig, a number less than zero is returned.  If \c b is
1242 *          better, then a number greater than zero is return.  If both are
1243 *          equal, zero is returned.
1244 * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1245 */
1246static int
1247fbconfig_compare(const __GLcontextModes * const *const a,
1248                 const __GLcontextModes * const *const b)
1249{
1250   /* The order of these comparisons must NOT change.  It is defined by
1251    * the GLX 1.3 spec and ARB_multisample.
1252    */
1253
1254   PREFER_SMALLER(visualSelectGroup);
1255
1256   /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
1257    * GLX_NON_CONFORMANT_CONFIG.  It just so happens that this is the
1258    * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
1259    */
1260   PREFER_SMALLER(visualRating);
1261
1262   /* This isn't quite right.  It is supposed to compare the sum of the
1263    * components the user specifically set minimums for.
1264    */
1265   PREFER_LARGER_OR_ZERO(redBits);
1266   PREFER_LARGER_OR_ZERO(greenBits);
1267   PREFER_LARGER_OR_ZERO(blueBits);
1268   PREFER_LARGER_OR_ZERO(alphaBits);
1269
1270   PREFER_SMALLER(rgbBits);
1271
1272   if (((*a)->doubleBufferMode != (*b)->doubleBufferMode)) {
1273      /* Prefer single-buffer.
1274       */
1275      return (!(*a)->doubleBufferMode) ? -1 : 1;
1276   }
1277
1278   PREFER_SMALLER(numAuxBuffers);
1279
1280   PREFER_LARGER_OR_ZERO(depthBits);
1281   PREFER_SMALLER(stencilBits);
1282
1283   /* This isn't quite right.  It is supposed to compare the sum of the
1284    * components the user specifically set minimums for.
1285    */
1286   PREFER_LARGER_OR_ZERO(accumRedBits);
1287   PREFER_LARGER_OR_ZERO(accumGreenBits);
1288   PREFER_LARGER_OR_ZERO(accumBlueBits);
1289   PREFER_LARGER_OR_ZERO(accumAlphaBits);
1290
1291   PREFER_SMALLER(visualType);
1292
1293   /* None of the multisample specs say where this comparison should happen,
1294    * so I put it near the end.
1295    */
1296   PREFER_SMALLER(sampleBuffers);
1297   PREFER_SMALLER(samples);
1298
1299   /* None of the pbuffer or fbconfig specs say that this comparison needs
1300    * to happen at all, but it seems like it should.
1301    */
1302   PREFER_LARGER(maxPbufferWidth);
1303   PREFER_LARGER(maxPbufferHeight);
1304   PREFER_LARGER(maxPbufferPixels);
1305
1306   return 0;
1307}
1308
1309
1310/**
1311 * Selects and sorts a subset of the supplied configs based on the attributes.
1312 * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig,
1313 * and \c glXChooseFBConfigSGIX.
1314 *
1315 * \param configs   Array of pointers to possible configs.  The elements of
1316 *                  this array that do not meet the criteria will be set to
1317 *                  NULL.  The remaining elements will be sorted according to
1318 *                  the various visual / FBConfig selection rules.
1319 * \param num_configs  Number of elements in the \c configs array.
1320 * \param attribList   Attributes used select from \c configs.  This array is
1321 *                     terminated by a \c None tag.  The array can either take
1322 *                     the form expected by \c glXChooseVisual (where boolean
1323 *                     tags do not have a value) or by \c glXChooseFBConfig
1324 *                     (where every tag has a value).
1325 * \param fbconfig_style_tags  Selects whether \c attribList is in
1326 *                             \c glXChooseVisual style or
1327 *                             \c glXChooseFBConfig style.
1328 * \returns The number of valid elements left in \c configs.
1329 *
1330 * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1331 */
1332static int
1333choose_visual(__GLcontextModes ** configs, int num_configs,
1334              const int *attribList, GLboolean fbconfig_style_tags)
1335{
1336   __GLcontextModes test_config;
1337   int base;
1338   int i;
1339
1340   /* This is a fairly direct implementation of the selection method
1341    * described by GLX_SGIX_fbconfig.  Start by culling out all the
1342    * configs that are not compatible with the selected parameter
1343    * list.
1344    */
1345
1346   init_fbconfig_for_chooser(&test_config, fbconfig_style_tags);
1347   __glXInitializeVisualConfigFromTags(&test_config, 512,
1348                                       (const INT32 *) attribList,
1349                                       GL_TRUE, fbconfig_style_tags);
1350
1351   base = 0;
1352   for (i = 0; i < num_configs; i++) {
1353      if (fbconfigs_compatible(&test_config, configs[i])) {
1354         configs[base] = configs[i];
1355         base++;
1356      }
1357   }
1358
1359   if (base == 0) {
1360      return 0;
1361   }
1362
1363   if (base < num_configs) {
1364      (void) memset(&configs[base], 0, sizeof(void *) * (num_configs - base));
1365   }
1366
1367   /* After the incompatible configs are removed, the resulting
1368    * list is sorted according to the rules set out in the various
1369    * specifications.
1370    */
1371
1372   qsort(configs, base, sizeof(__GLcontextModes *),
1373         (int (*)(const void *, const void *)) fbconfig_compare);
1374   return base;
1375}
1376
1377
1378
1379
1380/*
1381** Return the visual that best matches the template.  Return None if no
1382** visual matches the template.
1383*/
1384PUBLIC XVisualInfo *
1385glXChooseVisual(Display * dpy, int screen, int *attribList)
1386{
1387   XVisualInfo *visualList = NULL;
1388   __GLXdisplayPrivate *priv;
1389   __GLXscreenConfigs *psc;
1390   __GLcontextModes test_config;
1391   __GLcontextModes *modes;
1392   const __GLcontextModes *best_config = NULL;
1393
1394   /*
1395    ** Get a list of all visuals, return if list is empty
1396    */
1397   if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1398      return None;
1399   }
1400
1401
1402   /*
1403    ** Build a template from the defaults and the attribute list
1404    ** Free visual list and return if an unexpected token is encountered
1405    */
1406   init_fbconfig_for_chooser(&test_config, GL_FALSE);
1407   __glXInitializeVisualConfigFromTags(&test_config, 512,
1408                                       (const INT32 *) attribList,
1409                                       GL_TRUE, GL_FALSE);
1410
1411   /*
1412    ** Eliminate visuals that don't meet minimum requirements
1413    ** Compute a score for those that do
1414    ** Remember which visual, if any, got the highest score
1415    ** If no visual is acceptable, return None
1416    ** Otherwise, create an XVisualInfo list with just the selected X visual
1417    ** and return this.
1418    */
1419   for (modes = psc->visuals; modes != NULL; modes = modes->next) {
1420      if (fbconfigs_compatible(&test_config, modes)
1421          && ((best_config == NULL)
1422              ||
1423              (fbconfig_compare
1424               ((const __GLcontextModes * const *const) &modes,
1425                &best_config) < 0))) {
1426         XVisualInfo visualTemplate;
1427         XVisualInfo *newList;
1428         int i;
1429
1430         visualTemplate.screen = screen;
1431         visualTemplate.visualid = modes->visualID;
1432         newList = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask,
1433                                  &visualTemplate, &i);
1434
1435         if (newList) {
1436            Xfree(visualList);
1437            visualList = newList;
1438            best_config = modes;
1439         }
1440      }
1441   }
1442
1443   return visualList;
1444}
1445
1446
1447PUBLIC const char *
1448glXQueryExtensionsString(Display * dpy, int screen)
1449{
1450   __GLXscreenConfigs *psc;
1451   __GLXdisplayPrivate *priv;
1452
1453   if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1454      return NULL;
1455   }
1456
1457   if (!psc->effectiveGLXexts) {
1458      if (!psc->serverGLXexts) {
1459         psc->serverGLXexts =
1460            __glXQueryServerString(dpy, priv->majorOpcode, screen,
1461                                   GLX_EXTENSIONS);
1462      }
1463
1464      __glXCalculateUsableExtensions(psc,
1465#ifdef GLX_DIRECT_RENDERING
1466                                     (psc->driScreen != NULL),
1467#else
1468                                     GL_FALSE,
1469#endif
1470                                     priv->minorVersion);
1471   }
1472
1473   return psc->effectiveGLXexts;
1474}
1475
1476PUBLIC const char *
1477glXGetClientString(Display * dpy, int name)
1478{
1479   (void) dpy;
1480
1481   switch (name) {
1482   case GLX_VENDOR:
1483      return (__glXGLXClientVendorName);
1484   case GLX_VERSION:
1485      return (__glXGLXClientVersion);
1486   case GLX_EXTENSIONS:
1487      return (__glXGetClientExtensions());
1488   default:
1489      return NULL;
1490   }
1491}
1492
1493PUBLIC const char *
1494glXQueryServerString(Display * dpy, int screen, int name)
1495{
1496   __GLXscreenConfigs *psc;
1497   __GLXdisplayPrivate *priv;
1498   const char **str;
1499
1500
1501   if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1502      return NULL;
1503   }
1504
1505   switch (name) {
1506   case GLX_VENDOR:
1507      str = &priv->serverGLXvendor;
1508      break;
1509   case GLX_VERSION:
1510      str = &priv->serverGLXversion;
1511      break;
1512   case GLX_EXTENSIONS:
1513      str = &psc->serverGLXexts;
1514      break;
1515   default:
1516      return NULL;
1517   }
1518
1519   if (*str == NULL) {
1520      *str = __glXQueryServerString(dpy, priv->majorOpcode, screen, name);
1521   }
1522
1523   return *str;
1524}
1525
1526void
1527__glXClientInfo(Display * dpy, int opcode)
1528{
1529   char *ext_str = __glXGetClientGLExtensionString();
1530   int size = strlen(ext_str) + 1;
1531
1532#ifdef USE_XCB
1533   xcb_connection_t *c = XGetXCBConnection(dpy);
1534   xcb_glx_client_info(c,
1535                       GLX_MAJOR_VERSION, GLX_MINOR_VERSION, size, ext_str);
1536#else
1537   xGLXClientInfoReq *req;
1538
1539   /* Send the glXClientInfo request */
1540   LockDisplay(dpy);
1541   GetReq(GLXClientInfo, req);
1542   req->reqType = opcode;
1543   req->glxCode = X_GLXClientInfo;
1544   req->major = GLX_MAJOR_VERSION;
1545   req->minor = GLX_MINOR_VERSION;
1546
1547   req->length += (size + 3) >> 2;
1548   req->numbytes = size;
1549   Data(dpy, ext_str, size);
1550
1551   UnlockDisplay(dpy);
1552   SyncHandle();
1553#endif /* USE_XCB */
1554
1555   Xfree(ext_str);
1556}
1557
1558
1559/*
1560** EXT_import_context
1561*/
1562
1563PUBLIC Display *
1564glXGetCurrentDisplay(void)
1565{
1566   GLXContext gc = __glXGetCurrentContext();
1567   if (NULL == gc)
1568      return NULL;
1569   return gc->currentDpy;
1570}
1571
1572PUBLIC
1573GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
1574          glXGetCurrentDisplay)
1575
1576/**
1577 * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests
1578 * to the X-server.
1579 *
1580 * \param dpy  Display where \c ctx was created.
1581 * \param ctx  Context to query.
1582 * \returns  \c Success on success.  \c GLX_BAD_CONTEXT if \c ctx is invalid,
1583 *           or zero if the request failed due to internal problems (i.e.,
1584 *           unable to allocate temporary memory, etc.)
1585 *
1586 * \note
1587 * This function dynamically determines whether to use the EXT_import_context
1588 * version of the protocol or the GLX 1.3 version of the protocol.
1589 */
1590static int __glXQueryContextInfo(Display * dpy, GLXContext ctx)
1591{
1592   __GLXdisplayPrivate *priv = __glXInitialize(dpy);
1593   xGLXQueryContextReply reply;
1594   CARD8 opcode;
1595   GLuint numValues;
1596   int retval;
1597
1598   if (ctx == NULL) {
1599      return GLX_BAD_CONTEXT;
1600   }
1601   opcode = __glXSetupForCommand(dpy);
1602   if (!opcode) {
1603      return 0;
1604   }
1605
1606   /* Send the glXQueryContextInfoEXT request */
1607   LockDisplay(dpy);
1608
1609   if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
1610      xGLXQueryContextReq *req;
1611
1612      GetReq(GLXQueryContext, req);
1613
1614      req->reqType = opcode;
1615      req->glxCode = X_GLXQueryContext;
1616      req->context = (unsigned int) (ctx->xid);
1617   }
1618   else {
1619      xGLXVendorPrivateReq *vpreq;
1620      xGLXQueryContextInfoEXTReq *req;
1621
1622      GetReqExtra(GLXVendorPrivate,
1623                  sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
1624                  vpreq);
1625      req = (xGLXQueryContextInfoEXTReq *) vpreq;
1626      req->reqType = opcode;
1627      req->glxCode = X_GLXVendorPrivateWithReply;
1628      req->vendorCode = X_GLXvop_QueryContextInfoEXT;
1629      req->context = (unsigned int) (ctx->xid);
1630   }
1631
1632   _XReply(dpy, (xReply *) & reply, 0, False);
1633
1634   numValues = reply.n;
1635   if (numValues == 0)
1636      retval = Success;
1637   else if (numValues > __GLX_MAX_CONTEXT_PROPS)
1638      retval = 0;
1639   else {
1640      int *propList, *pProp;
1641      int nPropListBytes;
1642
1643      nPropListBytes = numValues << 3;
1644      propList = (int *) Xmalloc(nPropListBytes);
1645      if (NULL == propList) {
1646         retval = 0;
1647      }
1648      else {
1649	 unsigned i;
1650
1651         _XRead(dpy, (char *) propList, nPropListBytes);
1652         pProp = propList;
1653         for (i = 0; i < numValues; i++) {
1654            switch (*pProp++) {
1655            case GLX_SHARE_CONTEXT_EXT:
1656               ctx->share_xid = *pProp++;
1657               break;
1658            case GLX_VISUAL_ID_EXT:
1659               ctx->mode =
1660                  _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++);
1661               break;
1662            case GLX_SCREEN:
1663               ctx->screen = *pProp++;
1664               break;
1665            case GLX_FBCONFIG_ID:
1666               ctx->mode =
1667                  _gl_context_modes_find_fbconfig(ctx->psc->configs,
1668                                                  *pProp++);
1669               break;
1670            case GLX_RENDER_TYPE:
1671               ctx->renderType = *pProp++;
1672               break;
1673            default:
1674               pProp++;
1675               continue;
1676            }
1677         }
1678         Xfree((char *) propList);
1679         retval = Success;
1680      }
1681   }
1682   UnlockDisplay(dpy);
1683   SyncHandle();
1684   return retval;
1685}
1686
1687PUBLIC int
1688glXQueryContext(Display * dpy, GLXContext ctx, int attribute, int *value)
1689{
1690   int retVal;
1691
1692   /* get the information from the server if we don't have it already */
1693#ifdef GLX_DIRECT_RENDERING
1694   if (!ctx->driContext && (ctx->mode == NULL)) {
1695#else
1696   if (ctx->mode == NULL) {
1697#endif
1698      retVal = __glXQueryContextInfo(dpy, ctx);
1699      if (Success != retVal)
1700         return retVal;
1701   }
1702   switch (attribute) {
1703   case GLX_SHARE_CONTEXT_EXT:
1704      *value = (int) (ctx->share_xid);
1705      break;
1706   case GLX_VISUAL_ID_EXT:
1707      *value = ctx->mode ? ctx->mode->visualID : None;
1708      break;
1709   case GLX_SCREEN:
1710      *value = (int) (ctx->screen);
1711      break;
1712   case GLX_FBCONFIG_ID:
1713      *value = ctx->mode ? ctx->mode->fbconfigID : None;
1714      break;
1715   case GLX_RENDER_TYPE:
1716      *value = (int) (ctx->renderType);
1717      break;
1718   default:
1719      return GLX_BAD_ATTRIBUTE;
1720   }
1721   return Success;
1722}
1723
1724PUBLIC
1725GLX_ALIAS(int, glXQueryContextInfoEXT,
1726          (Display * dpy, GLXContext ctx, int attribute, int *value),
1727          (dpy, ctx, attribute, value), glXQueryContext)
1728
1729PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx)
1730{
1731   return ctx->xid;
1732}
1733
1734PUBLIC GLXContext
1735glXImportContextEXT(Display * dpy, GLXContextID contextID)
1736{
1737   GLXContext ctx;
1738
1739   if (contextID == None) {
1740      return NULL;
1741   }
1742   if (__glXIsDirect(dpy, contextID)) {
1743      return NULL;
1744   }
1745
1746   ctx = AllocateGLXContext(dpy);
1747   if (NULL != ctx) {
1748      ctx->xid = contextID;
1749      ctx->imported = GL_TRUE;
1750
1751      if (Success != __glXQueryContextInfo(dpy, ctx)) {
1752	 __glXFreeContext(ctx);
1753	 ctx = NULL;
1754      }
1755   }
1756   return ctx;
1757}
1758
1759PUBLIC void
1760glXFreeContextEXT(Display * dpy, GLXContext ctx)
1761{
1762   DestroyContext(dpy, ctx);
1763}
1764
1765
1766
1767/*
1768 * GLX 1.3 functions - these are just stubs for now!
1769 */
1770
1771PUBLIC GLXFBConfig *
1772glXChooseFBConfig(Display * dpy, int screen,
1773                  const int *attribList, int *nitems)
1774{
1775   __GLcontextModes **config_list;
1776   int list_size;
1777
1778
1779   config_list = (__GLcontextModes **)
1780      glXGetFBConfigs(dpy, screen, &list_size);
1781
1782   if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) {
1783      list_size = choose_visual(config_list, list_size, attribList, GL_TRUE);
1784      if (list_size == 0) {
1785         XFree(config_list);
1786         config_list = NULL;
1787      }
1788   }
1789
1790   *nitems = list_size;
1791   return (GLXFBConfig *) config_list;
1792}
1793
1794
1795PUBLIC GLXContext
1796glXCreateNewContext(Display * dpy, GLXFBConfig config,
1797                    int renderType, GLXContext shareList, Bool allowDirect)
1798{
1799   const __GLcontextModes *const fbconfig =
1800      (const __GLcontextModes *const) config;
1801
1802   return CreateContext(dpy, fbconfig->fbconfigID, fbconfig, shareList,
1803                        allowDirect, X_GLXCreateNewContext, renderType,
1804			fbconfig->screen);
1805}
1806
1807
1808PUBLIC GLXDrawable
1809glXGetCurrentReadDrawable(void)
1810{
1811   GLXContext gc = __glXGetCurrentContext();
1812   return gc->currentReadable;
1813}
1814
1815
1816PUBLIC GLXFBConfig *
1817glXGetFBConfigs(Display * dpy, int screen, int *nelements)
1818{
1819   __GLXdisplayPrivate *priv = __glXInitialize(dpy);
1820   __GLcontextModes **config = NULL;
1821   int i;
1822
1823   *nelements = 0;
1824   if (priv && (priv->screenConfigs != NULL)
1825       && (screen >= 0) && (screen <= ScreenCount(dpy))
1826       && (priv->screenConfigs[screen].configs != NULL)
1827       && (priv->screenConfigs[screen].configs->fbconfigID
1828	   != (int) GLX_DONT_CARE)) {
1829      unsigned num_configs = 0;
1830      __GLcontextModes *modes;
1831
1832
1833      for (modes = priv->screenConfigs[screen].configs; modes != NULL;
1834           modes = modes->next) {
1835         if (modes->fbconfigID != (int) GLX_DONT_CARE) {
1836            num_configs++;
1837         }
1838      }
1839
1840      config = (__GLcontextModes **) Xmalloc(sizeof(__GLcontextModes *)
1841                                             * num_configs);
1842      if (config != NULL) {
1843         *nelements = num_configs;
1844         i = 0;
1845         for (modes = priv->screenConfigs[screen].configs; modes != NULL;
1846              modes = modes->next) {
1847            if (modes->fbconfigID != (int) GLX_DONT_CARE) {
1848               config[i] = modes;
1849               i++;
1850            }
1851         }
1852      }
1853   }
1854   return (GLXFBConfig *) config;
1855}
1856
1857
1858PUBLIC int
1859glXGetFBConfigAttrib(Display * dpy, GLXFBConfig config,
1860                     int attribute, int *value)
1861{
1862   __GLcontextModes *const modes = ValidateGLXFBConfig(dpy, config);
1863
1864   return (modes != NULL)
1865      ? _gl_get_context_mode_data(modes, attribute, value)
1866      : GLXBadFBConfig;
1867}
1868
1869
1870PUBLIC XVisualInfo *
1871glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config)
1872{
1873   XVisualInfo visualTemplate;
1874   __GLcontextModes *fbconfig = (__GLcontextModes *) config;
1875   int count;
1876
1877   /*
1878    ** Get a list of all visuals, return if list is empty
1879    */
1880   visualTemplate.visualid = fbconfig->visualID;
1881   return XGetVisualInfo(dpy, VisualIDMask, &visualTemplate, &count);
1882}
1883
1884
1885/*
1886** GLX_SGI_swap_control
1887*/
1888static int
1889__glXSwapIntervalSGI(int interval)
1890{
1891   xGLXVendorPrivateReq *req;
1892   GLXContext gc = __glXGetCurrentContext();
1893   __GLXscreenConfigs *psc;
1894   Display *dpy;
1895   CARD32 *interval_ptr;
1896   CARD8 opcode;
1897
1898   if (gc == NULL) {
1899      return GLX_BAD_CONTEXT;
1900   }
1901
1902   if (interval <= 0) {
1903      return GLX_BAD_VALUE;
1904   }
1905
1906#ifdef __DRI_SWAP_CONTROL
1907   if (gc->driContext) {
1908      __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
1909							    gc->screen );
1910      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
1911						  gc->currentDrawable,
1912						  NULL);
1913      if (psc->swapControl != NULL && pdraw != NULL) {
1914	 psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
1915	 return 0;
1916      }
1917      else if (pdraw == NULL) {
1918	 return GLX_BAD_CONTEXT;
1919      }
1920   }
1921#endif
1922   psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1923
1924#ifdef GLX_DIRECT_RENDERING
1925   if (gc->driContext && psc->driScreen && psc->driScreen->setSwapInterval) {
1926      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
1927						  gc->currentDrawable,
1928						  NULL);
1929      psc->driScreen->setSwapInterval(pdraw, interval);
1930      return 0;
1931   }
1932#endif
1933
1934   dpy = gc->currentDpy;
1935   opcode = __glXSetupForCommand(dpy);
1936   if (!opcode) {
1937      return 0;
1938   }
1939
1940   /* Send the glXSwapIntervalSGI request */
1941   LockDisplay(dpy);
1942   GetReqExtra(GLXVendorPrivate, sizeof(CARD32), req);
1943   req->reqType = opcode;
1944   req->glxCode = X_GLXVendorPrivate;
1945   req->vendorCode = X_GLXvop_SwapIntervalSGI;
1946   req->contextTag = gc->currentContextTag;
1947
1948   interval_ptr = (CARD32 *) (req + 1);
1949   *interval_ptr = interval;
1950
1951   UnlockDisplay(dpy);
1952   SyncHandle();
1953   XFlush(dpy);
1954
1955   return 0;
1956}
1957
1958
1959/*
1960** GLX_MESA_swap_control
1961*/
1962static int
1963__glXSwapIntervalMESA(unsigned int interval)
1964{
1965   GLXContext gc = __glXGetCurrentContext();
1966
1967#ifdef __DRI_SWAP_CONTROL
1968   if (gc != NULL && gc->driContext) {
1969      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
1970                                                          gc->screen);
1971
1972      if ((psc != NULL) && (psc->driScreen != NULL)) {
1973         __GLXDRIdrawable *pdraw =
1974            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
1975         if (psc->swapControl != NULL && pdraw != NULL) {
1976            psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
1977            return 0;
1978         }
1979      }
1980   }
1981#endif
1982
1983#ifdef GLX_DIRECT_RENDERING
1984   if (gc != NULL && gc->driContext) {
1985      __GLXscreenConfigs *psc;
1986
1987      psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1988      if (psc->driScreen && psc->driScreen->setSwapInterval) {
1989         __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
1990						     gc->currentDrawable, NULL);
1991	 psc->driScreen->setSwapInterval(pdraw, interval);
1992	 return 0;
1993      }
1994   }
1995#endif
1996
1997   return GLX_BAD_CONTEXT;
1998}
1999
2000
2001static int
2002__glXGetSwapIntervalMESA(void)
2003{
2004#ifdef __DRI_SWAP_CONTROL
2005   GLXContext gc = __glXGetCurrentContext();
2006
2007   if (gc != NULL && gc->driContext) {
2008      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
2009                                                          gc->screen);
2010
2011      if ((psc != NULL) && (psc->driScreen != NULL)) {
2012         __GLXDRIdrawable *pdraw =
2013            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
2014         if (psc->swapControl != NULL && pdraw != NULL) {
2015            return psc->swapControl->getSwapInterval(pdraw->driDrawable);
2016         }
2017      }
2018   }
2019#endif
2020
2021#ifdef GLX_DIRECT_RENDERING
2022   if (gc != NULL && gc->driContext) {
2023      __GLXscreenConfigs *psc;
2024
2025      psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
2026      if (psc->driScreen && psc->driScreen->getSwapInterval) {
2027         __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
2028						     gc->currentDrawable, NULL);
2029	 return psc->driScreen->getSwapInterval(pdraw);
2030      }
2031   }
2032#endif
2033
2034   return 0;
2035}
2036
2037
2038/*
2039** GLX_MESA_swap_frame_usage
2040*/
2041
2042static GLint
2043__glXBeginFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
2044{
2045   int status = GLX_BAD_CONTEXT;
2046#ifdef __DRI_FRAME_TRACKING
2047   int screen = 0;
2048   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
2049   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
2050
2051   if (pdraw != NULL && psc->frameTracking != NULL)
2052      status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE);
2053#else
2054   (void) dpy;
2055   (void) drawable;
2056#endif
2057   return status;
2058}
2059
2060
2061static GLint
2062__glXEndFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
2063{
2064   int status = GLX_BAD_CONTEXT;
2065#ifdef __DRI_FRAME_TRACKING
2066   int screen = 0;
2067   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
2068   __GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen);
2069
2070   if (pdraw != NULL && psc->frameTracking != NULL)
2071      status = psc->frameTracking->frameTracking(pdraw->driDrawable,
2072                                                 GL_FALSE);
2073#else
2074   (void) dpy;
2075   (void) drawable;
2076#endif
2077   return status;
2078}
2079
2080
2081static GLint
2082__glXGetFrameUsageMESA(Display * dpy, GLXDrawable drawable, GLfloat * usage)
2083{
2084   int status = GLX_BAD_CONTEXT;
2085#ifdef __DRI_FRAME_TRACKING
2086   int screen = 0;
2087   __GLXDRIdrawable *const pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
2088   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
2089
2090   if (pdraw != NULL && psc->frameTracking != NULL) {
2091      int64_t sbc, missedFrames;
2092      float lastMissedUsage;
2093
2094      status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
2095                                                      &sbc,
2096                                                      &missedFrames,
2097                                                      &lastMissedUsage,
2098                                                      usage);
2099   }
2100#else
2101   (void) dpy;
2102   (void) drawable;
2103   (void) usage;
2104#endif
2105   return status;
2106}
2107
2108
2109static GLint
2110__glXQueryFrameTrackingMESA(Display * dpy, GLXDrawable drawable,
2111                            int64_t * sbc, int64_t * missedFrames,
2112                            GLfloat * lastMissedUsage)
2113{
2114   int status = GLX_BAD_CONTEXT;
2115#ifdef __DRI_FRAME_TRACKING
2116   int screen = 0;
2117   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
2118   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
2119
2120   if (pdraw != NULL && psc->frameTracking != NULL) {
2121      float usage;
2122
2123      status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
2124                                                      sbc, missedFrames,
2125                                                      lastMissedUsage,
2126                                                      &usage);
2127   }
2128#else
2129   (void) dpy;
2130   (void) drawable;
2131   (void) sbc;
2132   (void) missedFrames;
2133   (void) lastMissedUsage;
2134#endif
2135   return status;
2136}
2137
2138
2139/*
2140** GLX_SGI_video_sync
2141*/
2142static int
2143__glXGetVideoSyncSGI(unsigned int *count)
2144{
2145   int64_t ust, msc, sbc;
2146   int ret;
2147   GLXContext gc = __glXGetCurrentContext();
2148   __GLXscreenConfigs *psc;
2149#ifdef GLX_DIRECT_RENDERING
2150   __GLXDRIdrawable *pdraw;
2151#endif
2152
2153   if (!gc)
2154      return GLX_BAD_CONTEXT;
2155
2156#ifdef GLX_DIRECT_RENDERING
2157   if (!gc->driContext)
2158      return GLX_BAD_CONTEXT;
2159#endif
2160
2161   psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen);
2162#ifdef GLX_DIRECT_RENDERING
2163   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
2164#endif
2165
2166   /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
2167    * FIXME: there should be a GLX encoding for this call.  I can find no
2168    * FIXME: documentation for the GLX encoding.
2169    */
2170#ifdef __DRI_MEDIA_STREAM_COUNTER
2171   if ( psc->msc && psc->driScreen ) {
2172      ret = (*psc->msc->getDrawableMSC)(psc->__driScreen,
2173					pdraw->driDrawable, &msc);
2174      *count = (unsigned) msc;
2175
2176      return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
2177   }
2178#endif
2179
2180#ifdef GLX_DIRECT_RENDERING
2181   if (psc->driScreen && psc->driScreen->getDrawableMSC) {
2182      ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc);
2183      *count = (unsigned) msc;
2184      return (ret == True) ? 0 : GLX_BAD_CONTEXT;
2185   }
2186#endif
2187
2188   return GLX_BAD_CONTEXT;
2189}
2190
2191static int
2192__glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
2193{
2194   GLXContext gc = __glXGetCurrentContext();
2195   __GLXscreenConfigs *psc;
2196#ifdef GLX_DIRECT_RENDERING
2197   __GLXDRIdrawable *pdraw;
2198#endif
2199   int64_t ust, msc, sbc;
2200   int ret;
2201
2202   if (divisor <= 0 || remainder < 0)
2203      return GLX_BAD_VALUE;
2204
2205   if (!gc)
2206      return GLX_BAD_CONTEXT;
2207
2208#ifdef GLX_DIRECT_RENDERING
2209   if (!gc->driContext)
2210      return GLX_BAD_CONTEXT;
2211#endif
2212
2213   psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
2214#ifdef GLX_DIRECT_RENDERING
2215   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
2216#endif
2217
2218#ifdef __DRI_MEDIA_STREAM_COUNTER
2219   if (psc->msc != NULL && psc->driScreen ) {
2220      ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0,
2221				    divisor, remainder, &msc, &sbc);
2222      *count = (unsigned) msc;
2223      return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
2224   }
2225#endif
2226
2227#ifdef GLX_DIRECT_RENDERING
2228   if (psc->driScreen && psc->driScreen->waitForMSC) {
2229      ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc,
2230				       &sbc);
2231      *count = (unsigned) msc;
2232      return (ret == True) ? 0 : GLX_BAD_CONTEXT;
2233   }
2234#endif
2235
2236   return GLX_BAD_CONTEXT;
2237}
2238
2239
2240/*
2241** GLX_SGIX_fbconfig
2242** Many of these functions are aliased to GLX 1.3 entry points in the
2243** GLX_functions table.
2244*/
2245
2246PUBLIC
2247GLX_ALIAS(int, glXGetFBConfigAttribSGIX,
2248          (Display * dpy, GLXFBConfigSGIX config, int attribute, int *value),
2249          (dpy, config, attribute, value), glXGetFBConfigAttrib)
2250
2251PUBLIC GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
2252                 (Display * dpy, int screen, int *attrib_list,
2253                  int *nelements), (dpy, screen, attrib_list, nelements),
2254                 glXChooseFBConfig)
2255
2256PUBLIC GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
2257                 (Display * dpy, GLXFBConfigSGIX config),
2258                 (dpy, config), glXGetVisualFromFBConfig)
2259
2260PUBLIC GLXPixmap
2261glXCreateGLXPixmapWithConfigSGIX(Display * dpy,
2262                                 GLXFBConfigSGIX config,
2263                                 Pixmap pixmap)
2264{
2265   xGLXVendorPrivateWithReplyReq *vpreq;
2266   xGLXCreateGLXPixmapWithConfigSGIXReq *req;
2267   GLXPixmap xid = None;
2268   CARD8 opcode;
2269   const __GLcontextModes *const fbconfig = (__GLcontextModes *) config;
2270   __GLXscreenConfigs *psc;
2271
2272
2273   if ((dpy == NULL) || (config == NULL)) {
2274      return None;
2275   }
2276
2277   psc = GetGLXScreenConfigs(dpy, fbconfig->screen);
2278   if ((psc != NULL)
2279       && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
2280      opcode = __glXSetupForCommand(dpy);
2281      if (!opcode) {
2282         return None;
2283      }
2284
2285      /* Send the glXCreateGLXPixmapWithConfigSGIX request */
2286      LockDisplay(dpy);
2287      GetReqExtra(GLXVendorPrivateWithReply,
2288                  sz_xGLXCreateGLXPixmapWithConfigSGIXReq -
2289                  sz_xGLXVendorPrivateWithReplyReq, vpreq);
2290      req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) vpreq;
2291      req->reqType = opcode;
2292      req->glxCode = X_GLXVendorPrivateWithReply;
2293      req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
2294      req->screen = fbconfig->screen;
2295      req->fbconfig = fbconfig->fbconfigID;
2296      req->pixmap = pixmap;
2297      req->glxpixmap = xid = XAllocID(dpy);
2298      UnlockDisplay(dpy);
2299      SyncHandle();
2300   }
2301
2302   return xid;
2303}
2304
2305PUBLIC GLXContext
2306glXCreateContextWithConfigSGIX(Display * dpy,
2307                               GLXFBConfigSGIX config, int renderType,
2308                               GLXContext shareList, Bool allowDirect)
2309{
2310   GLXContext gc = NULL;
2311   const __GLcontextModes *const fbconfig = (__GLcontextModes *) config;
2312   __GLXscreenConfigs *psc;
2313
2314
2315   if ((dpy == NULL) || (config == NULL)) {
2316      return None;
2317   }
2318
2319   psc = GetGLXScreenConfigs(dpy, fbconfig->screen);
2320   if ((psc != NULL)
2321       && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
2322      gc = CreateContext(dpy, fbconfig->fbconfigID, fbconfig, shareList,
2323                         allowDirect,
2324			 X_GLXvop_CreateContextWithConfigSGIX, renderType,
2325			 fbconfig->screen);
2326   }
2327
2328   return gc;
2329}
2330
2331
2332PUBLIC GLXFBConfigSGIX
2333glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis)
2334{
2335   __GLXdisplayPrivate *priv;
2336   __GLXscreenConfigs *psc = NULL;
2337
2338   if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) != Success)
2339       && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)
2340       && (psc->configs->fbconfigID != (int) GLX_DONT_CARE)) {
2341      return (GLXFBConfigSGIX) _gl_context_modes_find_visual(psc->configs,
2342                                                             vis->visualid);
2343   }
2344
2345   return NULL;
2346}
2347
2348
2349/*
2350** GLX_SGIX_swap_group
2351*/
2352static void
2353__glXJoinSwapGroupSGIX(Display * dpy, GLXDrawable drawable,
2354                       GLXDrawable member)
2355{
2356   (void) dpy;
2357   (void) drawable;
2358   (void) member;
2359}
2360
2361
2362/*
2363** GLX_SGIX_swap_barrier
2364*/
2365static void
2366__glXBindSwapBarrierSGIX(Display * dpy, GLXDrawable drawable, int barrier)
2367{
2368   (void) dpy;
2369   (void) drawable;
2370   (void) barrier;
2371}
2372
2373static Bool
2374__glXQueryMaxSwapBarriersSGIX(Display * dpy, int screen, int *max)
2375{
2376   (void) dpy;
2377   (void) screen;
2378   (void) max;
2379   return False;
2380}
2381
2382
2383/*
2384** GLX_OML_sync_control
2385*/
2386static Bool
2387__glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
2388                      int64_t * ust, int64_t * msc, int64_t * sbc)
2389{
2390   __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
2391   int i, ret;
2392#ifdef GLX_DIRECT_RENDERING
2393   __GLXDRIdrawable *pdraw;
2394#endif
2395   __GLXscreenConfigs *psc;
2396
2397   if (!priv)
2398      return False;
2399
2400#ifdef GLX_DIRECT_RENDERING
2401   pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
2402#endif
2403   psc = &priv->screenConfigs[i];
2404
2405#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER)
2406   if (pdraw && psc->sbc && psc->msc)
2407      return ( (pdraw && psc->sbc && psc->msc)
2408	       && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0)
2409	       && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0)
2410	       && (__glXGetUST(ust) == 0) );
2411#endif
2412
2413#ifdef GLX_DIRECT_RENDERING
2414   if (pdraw && psc && psc->driScreen && psc->driScreen->getDrawableMSC) {
2415      ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc);
2416      return ret;
2417   }
2418#endif
2419
2420   return False;
2421}
2422
2423#ifdef GLX_DIRECT_RENDERING
2424_X_HIDDEN GLboolean
2425__driGetMscRateOML(__DRIdrawable * draw,
2426                   int32_t * numerator, int32_t * denominator, void *private)
2427{
2428#ifdef XF86VIDMODE
2429   __GLXscreenConfigs *psc;
2430   XF86VidModeModeLine mode_line;
2431   int dot_clock;
2432   int i;
2433   __GLXDRIdrawable *glxDraw = private;
2434
2435   (void) draw;
2436
2437   psc = glxDraw->psc;
2438   if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
2439       XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line)) {
2440      unsigned n = dot_clock * 1000;
2441      unsigned d = mode_line.vtotal * mode_line.htotal;
2442
2443# define V_INTERLACE 0x010
2444# define V_DBLSCAN   0x020
2445
2446      if (mode_line.flags & V_INTERLACE)
2447         n *= 2;
2448      else if (mode_line.flags & V_DBLSCAN)
2449         d *= 2;
2450
2451      /* The OML_sync_control spec requires that if the refresh rate is a
2452       * whole number, that the returned numerator be equal to the refresh
2453       * rate and the denominator be 1.
2454       */
2455
2456      if (n % d == 0) {
2457         n /= d;
2458         d = 1;
2459      }
2460      else {
2461         static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
2462
2463         /* This is a poor man's way to reduce a fraction.  It's far from
2464          * perfect, but it will work well enough for this situation.
2465          */
2466
2467         for (i = 0; f[i] != 0; i++) {
2468            while (n % f[i] == 0 && d % f[i] == 0) {
2469               d /= f[i];
2470               n /= f[i];
2471            }
2472         }
2473      }
2474
2475      *numerator = n;
2476      *denominator = d;
2477
2478      return True;
2479   }
2480   else
2481      return False;
2482#else
2483   (void) draw;
2484   (void) numerator;
2485   (void) denominator;
2486   (void) private;
2487
2488   return False;
2489#endif
2490}
2491#endif
2492
2493/**
2494 * Determine the refresh rate of the specified drawable and display.
2495 *
2496 * \param dpy          Display whose refresh rate is to be determined.
2497 * \param drawable     Drawable whose refresh rate is to be determined.
2498 * \param numerator    Numerator of the refresh rate.
2499 * \param demoninator  Denominator of the refresh rate.
2500 * \return  If the refresh rate for the specified display and drawable could
2501 *          be calculated, True is returned.  Otherwise False is returned.
2502 *
2503 * \note This function is implemented entirely client-side.  A lot of other
2504 *       functionality is required to export GLX_OML_sync_control, so on
2505 *       XFree86 this function can be called for direct-rendering contexts
2506 *       when GLX_OML_sync_control appears in the client extension string.
2507 */
2508
2509_X_HIDDEN GLboolean
2510__glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
2511                   int32_t * numerator, int32_t * denominator)
2512{
2513#if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
2514   __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL);
2515
2516   if (draw == NULL)
2517      return False;
2518
2519   return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw);
2520#else
2521   (void) dpy;
2522   (void) drawable;
2523   (void) numerator;
2524   (void) denominator;
2525#endif
2526   return False;
2527}
2528
2529
2530static int64_t
2531__glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
2532                       int64_t target_msc, int64_t divisor, int64_t remainder)
2533{
2534   GLXContext gc = __glXGetCurrentContext();
2535   int screen;
2536#ifdef GLX_DIRECT_RENDERING
2537   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
2538#endif
2539   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
2540
2541   if (!gc) /* no GLX for this */
2542      return -1;
2543
2544#ifdef GLX_DIRECT_RENDERING
2545   if (!pdraw || !gc->driContext)
2546      return -1;
2547#endif
2548
2549   /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2550    * error", but it also says "It [glXSwapBuffersMscOML] will return a value
2551    * of -1 if the function failed because of errors detected in the input
2552    * parameters"
2553    */
2554   if (divisor < 0 || remainder < 0 || target_msc < 0)
2555      return -1;
2556   if (divisor > 0 && remainder >= divisor)
2557      return -1;
2558
2559   if (target_msc == 0 && divisor == 0 && remainder == 0)
2560      remainder = 1;
2561
2562#ifdef __DRI_SWAP_BUFFER_COUNTER
2563   if (psc->counters != NULL)
2564      return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc,
2565					 divisor, remainder);
2566#endif
2567
2568#ifdef GLX_DIRECT_RENDERING
2569   if (psc->driScreen && psc->driScreen->swapBuffers)
2570      return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor,
2571					    remainder);
2572#endif
2573
2574   return -1;
2575}
2576
2577
2578static Bool
2579__glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
2580                   int64_t target_msc, int64_t divisor,
2581                   int64_t remainder, int64_t * ust,
2582                   int64_t * msc, int64_t * sbc)
2583{
2584   int screen;
2585#ifdef GLX_DIRECT_RENDERING
2586   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
2587#endif
2588   __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
2589   int ret;
2590
2591
2592   /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2593    * error", but the return type in the spec is Bool.
2594    */
2595   if (divisor < 0 || remainder < 0 || target_msc < 0)
2596      return False;
2597   if (divisor > 0 && remainder >= divisor)
2598      return False;
2599
2600#ifdef __DRI_MEDIA_STREAM_COUNTER
2601   if (pdraw != NULL && psc->msc != NULL) {
2602      ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, target_msc,
2603                                     divisor, remainder, msc, sbc);
2604
2605      /* __glXGetUST returns zero on success and non-zero on failure.
2606       * This function returns True on success and False on failure.
2607       */
2608      return ((ret == 0) && (__glXGetUST(ust) == 0));
2609   }
2610#endif
2611
2612#ifdef GLX_DIRECT_RENDERING
2613   if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
2614      ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder,
2615				       ust, msc, sbc);
2616      return ret;
2617   }
2618#endif
2619
2620   return False;
2621}
2622
2623
2624static Bool
2625__glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
2626                   int64_t target_sbc, int64_t * ust,
2627                   int64_t * msc, int64_t * sbc)
2628{
2629   int screen;
2630#ifdef GLX_DIRECT_RENDERING
2631   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
2632#endif
2633   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
2634   int ret;
2635
2636   /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
2637    * error", but the return type in the spec is Bool.
2638    */
2639   if (target_sbc < 0)
2640      return False;
2641#ifdef __DRI_SWAP_BUFFER_COUNTER
2642   if (pdraw != NULL && psc->sbc != NULL) {
2643      ret =
2644         (*psc->sbc->waitForSBC) (pdraw->driDrawable, target_sbc, msc, sbc);
2645
2646      /* __glXGetUST returns zero on success and non-zero on failure.
2647       * This function returns True on success and False on failure.
2648       */
2649      return ((ret == 0) && (__glXGetUST(ust) == 0));
2650   }
2651#endif
2652
2653#ifdef GLX_DIRECT_RENDERING
2654   if (pdraw && psc->driScreen && psc->driScreen->waitForSBC) {
2655      ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc);
2656      return ret;
2657   }
2658#endif
2659
2660   return False;
2661}
2662
2663
2664/**
2665 * GLX_MESA_allocate_memory
2666 */
2667/*@{*/
2668
2669PUBLIC void *
2670glXAllocateMemoryMESA(Display * dpy, int scrn,
2671                      size_t size, float readFreq,
2672                      float writeFreq, float priority)
2673{
2674#ifdef __DRI_ALLOCATE
2675   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
2676
2677   if (psc && psc->allocate)
2678      return (*psc->allocate->allocateMemory) (psc->__driScreen, size,
2679                                               readFreq, writeFreq, priority);
2680
2681#else
2682   (void) dpy;
2683   (void) scrn;
2684   (void) size;
2685   (void) readFreq;
2686   (void) writeFreq;
2687   (void) priority;
2688#endif /* __DRI_ALLOCATE */
2689
2690   return NULL;
2691}
2692
2693
2694PUBLIC void
2695glXFreeMemoryMESA(Display * dpy, int scrn, void *pointer)
2696{
2697#ifdef __DRI_ALLOCATE
2698   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
2699
2700   if (psc && psc->allocate)
2701      (*psc->allocate->freeMemory) (psc->__driScreen, pointer);
2702
2703#else
2704   (void) dpy;
2705   (void) scrn;
2706   (void) pointer;
2707#endif /* __DRI_ALLOCATE */
2708}
2709
2710
2711PUBLIC GLuint
2712glXGetMemoryOffsetMESA(Display * dpy, int scrn, const void *pointer)
2713{
2714#ifdef __DRI_ALLOCATE
2715   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
2716
2717   if (psc && psc->allocate)
2718      return (*psc->allocate->memoryOffset) (psc->__driScreen, pointer);
2719
2720#else
2721   (void) dpy;
2722   (void) scrn;
2723   (void) pointer;
2724#endif /* GLX_DIRECT_RENDERING */
2725
2726   return ~0L;
2727}
2728
2729/*@}*/
2730
2731
2732/**
2733 * Mesa extension stubs.  These will help reduce portability problems.
2734 */
2735/*@{*/
2736
2737/**
2738 * Release all buffers associated with the specified GLX drawable.
2739 *
2740 * \todo
2741 * This function was intended for stand-alone Mesa.  The issue there is that
2742 * the library doesn't get any notification when a window is closed.  In
2743 * DRI there is a similar but slightly different issue.  When GLX 1.3 is
2744 * supported, there are 3 different functions to destroy a drawable.  It
2745 * should be possible to create GLX protocol (or have it determine which
2746 * protocol to use based on the type of the drawable) to have one function
2747 * do the work of 3.  For the direct-rendering case, this function could
2748 * just call the driver's \c __DRIdrawableRec::destroyDrawable function.
2749 * This would reduce the frequency with which \c __driGarbageCollectDrawables
2750 * would need to be used.  This really should be done as part of the new DRI
2751 * interface work.
2752 *
2753 * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt
2754 *     __driGarbageCollectDrawables
2755 *     glXDestroyGLXPixmap
2756 *     glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
2757 *     glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
2758 */
2759static Bool
2760__glXReleaseBuffersMESA(Display * dpy, GLXDrawable d)
2761{
2762   (void) dpy;
2763   (void) d;
2764   return False;
2765}
2766
2767
2768PUBLIC GLXPixmap
2769glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual,
2770                       Pixmap pixmap, Colormap cmap)
2771{
2772   (void) dpy;
2773   (void) visual;
2774   (void) pixmap;
2775   (void) cmap;
2776   return 0;
2777}
2778
2779/*@}*/
2780
2781
2782/**
2783 * GLX_MESA_copy_sub_buffer
2784 */
2785#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
2786static void
2787__glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
2788                       int x, int y, int width, int height)
2789{
2790   xGLXVendorPrivateReq *req;
2791   GLXContext gc;
2792   GLXContextTag tag;
2793   CARD32 *drawable_ptr;
2794   INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
2795   CARD8 opcode;
2796
2797#ifdef __DRI_COPY_SUB_BUFFER
2798   int screen;
2799   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
2800   if (pdraw != NULL) {
2801      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
2802      if (psc->driScreen->copySubBuffer != NULL) {
2803         glFlush();
2804         (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height);
2805      }
2806
2807      return;
2808   }
2809#endif
2810
2811   opcode = __glXSetupForCommand(dpy);
2812   if (!opcode)
2813      return;
2814
2815   /*
2816    ** The calling thread may or may not have a current context.  If it
2817    ** does, send the context tag so the server can do a flush.
2818    */
2819   gc = __glXGetCurrentContext();
2820   if ((gc != NULL) && (dpy == gc->currentDpy) &&
2821       ((drawable == gc->currentDrawable) ||
2822        (drawable == gc->currentReadable))) {
2823      tag = gc->currentContextTag;
2824   }
2825   else {
2826      tag = 0;
2827   }
2828
2829   LockDisplay(dpy);
2830   GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4, req);
2831   req->reqType = opcode;
2832   req->glxCode = X_GLXVendorPrivate;
2833   req->vendorCode = X_GLXvop_CopySubBufferMESA;
2834   req->contextTag = tag;
2835
2836   drawable_ptr = (CARD32 *) (req + 1);
2837   x_ptr = (INT32 *) (drawable_ptr + 1);
2838   y_ptr = (INT32 *) (drawable_ptr + 2);
2839   w_ptr = (INT32 *) (drawable_ptr + 3);
2840   h_ptr = (INT32 *) (drawable_ptr + 4);
2841
2842   *drawable_ptr = drawable;
2843   *x_ptr = x;
2844   *y_ptr = y;
2845   *w_ptr = width;
2846   *h_ptr = height;
2847
2848   UnlockDisplay(dpy);
2849   SyncHandle();
2850}
2851
2852
2853/**
2854 * GLX_EXT_texture_from_pixmap
2855 */
2856/*@{*/
2857static void
2858__glXBindTexImageEXT(Display * dpy,
2859                     GLXDrawable drawable, int buffer, const int *attrib_list)
2860{
2861   xGLXVendorPrivateReq *req;
2862   GLXContext gc = __glXGetCurrentContext();
2863   CARD32 *drawable_ptr;
2864   INT32 *buffer_ptr;
2865   CARD32 *num_attrib_ptr;
2866   CARD32 *attrib_ptr;
2867   CARD8 opcode;
2868   unsigned int i;
2869
2870   if (gc == NULL)
2871      return;
2872
2873   i = 0;
2874   if (attrib_list) {
2875      while (attrib_list[i * 2] != None)
2876         i++;
2877   }
2878
2879#ifdef GLX_DIRECT_RENDERING
2880   if (gc->driContext) {
2881      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
2882
2883      if (pdraw != NULL) {
2884         if (pdraw->psc->texBuffer->base.version >= 2 &&
2885             pdraw->psc->texBuffer->setTexBuffer2 != NULL) {
2886            (*pdraw->psc->texBuffer->setTexBuffer2) (gc->__driContext,
2887                                                     pdraw->textureTarget,
2888                                                     pdraw->textureFormat,
2889                                                     pdraw->driDrawable);
2890         }
2891         else {
2892            (*pdraw->psc->texBuffer->setTexBuffer) (gc->__driContext,
2893                                                    pdraw->textureTarget,
2894                                                    pdraw->driDrawable);
2895         }
2896      }
2897      return;
2898   }
2899#endif
2900
2901   opcode = __glXSetupForCommand(dpy);
2902   if (!opcode)
2903      return;
2904
2905   LockDisplay(dpy);
2906   GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req);
2907   req->reqType = opcode;
2908   req->glxCode = X_GLXVendorPrivate;
2909   req->vendorCode = X_GLXvop_BindTexImageEXT;
2910   req->contextTag = gc->currentContextTag;
2911
2912   drawable_ptr = (CARD32 *) (req + 1);
2913   buffer_ptr = (INT32 *) (drawable_ptr + 1);
2914   num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
2915   attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);
2916
2917   *drawable_ptr = drawable;
2918   *buffer_ptr = buffer;
2919   *num_attrib_ptr = (CARD32) i;
2920
2921   i = 0;
2922   if (attrib_list) {
2923      while (attrib_list[i * 2] != None) {
2924         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
2925         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
2926         i++;
2927      }
2928   }
2929
2930   UnlockDisplay(dpy);
2931   SyncHandle();
2932}
2933
2934static void
2935__glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer)
2936{
2937   xGLXVendorPrivateReq *req;
2938   GLXContext gc = __glXGetCurrentContext();
2939   CARD32 *drawable_ptr;
2940   INT32 *buffer_ptr;
2941   CARD8 opcode;
2942
2943   if ((gc == NULL) || GC_IS_DIRECT(gc))
2944      return;
2945
2946   opcode = __glXSetupForCommand(dpy);
2947   if (!opcode)
2948      return;
2949
2950   LockDisplay(dpy);
2951   GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req);
2952   req->reqType = opcode;
2953   req->glxCode = X_GLXVendorPrivate;
2954   req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
2955   req->contextTag = gc->currentContextTag;
2956
2957   drawable_ptr = (CARD32 *) (req + 1);
2958   buffer_ptr = (INT32 *) (drawable_ptr + 1);
2959
2960   *drawable_ptr = drawable;
2961   *buffer_ptr = buffer;
2962
2963   UnlockDisplay(dpy);
2964   SyncHandle();
2965}
2966
2967/*@}*/
2968
2969/**
2970 * \c strdup is actually not a standard ANSI C or POSIX routine.
2971 * Irix will not define it if ANSI mode is in effect.
2972 *
2973 * \sa strdup
2974 */
2975_X_HIDDEN char *
2976__glXstrdup(const char *str)
2977{
2978   char *copy;
2979   copy = (char *) Xmalloc(strlen(str) + 1);
2980   if (!copy)
2981      return NULL;
2982   strcpy(copy, str);
2983   return copy;
2984}
2985
2986/*
2987** glXGetProcAddress support
2988*/
2989
2990struct name_address_pair
2991{
2992   const char *Name;
2993   GLvoid *Address;
2994};
2995
2996#define GLX_FUNCTION(f) { # f, (GLvoid *) f }
2997#define GLX_FUNCTION2(n,f) { # n, (GLvoid *) f }
2998
2999static const struct name_address_pair GLX_functions[] = {
3000   /*** GLX_VERSION_1_0 ***/
3001   GLX_FUNCTION(glXChooseVisual),
3002   GLX_FUNCTION(glXCopyContext),
3003   GLX_FUNCTION(glXCreateContext),
3004   GLX_FUNCTION(glXCreateGLXPixmap),
3005   GLX_FUNCTION(glXDestroyContext),
3006   GLX_FUNCTION(glXDestroyGLXPixmap),
3007   GLX_FUNCTION(glXGetConfig),
3008   GLX_FUNCTION(glXGetCurrentContext),
3009   GLX_FUNCTION(glXGetCurrentDrawable),
3010   GLX_FUNCTION(glXIsDirect),
3011   GLX_FUNCTION(glXMakeCurrent),
3012   GLX_FUNCTION(glXQueryExtension),
3013   GLX_FUNCTION(glXQueryVersion),
3014   GLX_FUNCTION(glXSwapBuffers),
3015   GLX_FUNCTION(glXUseXFont),
3016   GLX_FUNCTION(glXWaitGL),
3017   GLX_FUNCTION(glXWaitX),
3018
3019   /*** GLX_VERSION_1_1 ***/
3020   GLX_FUNCTION(glXGetClientString),
3021   GLX_FUNCTION(glXQueryExtensionsString),
3022   GLX_FUNCTION(glXQueryServerString),
3023
3024   /*** GLX_VERSION_1_2 ***/
3025   GLX_FUNCTION(glXGetCurrentDisplay),
3026
3027   /*** GLX_VERSION_1_3 ***/
3028   GLX_FUNCTION(glXChooseFBConfig),
3029   GLX_FUNCTION(glXCreateNewContext),
3030   GLX_FUNCTION(glXCreatePbuffer),
3031   GLX_FUNCTION(glXCreatePixmap),
3032   GLX_FUNCTION(glXCreateWindow),
3033   GLX_FUNCTION(glXDestroyPbuffer),
3034   GLX_FUNCTION(glXDestroyPixmap),
3035   GLX_FUNCTION(glXDestroyWindow),
3036   GLX_FUNCTION(glXGetCurrentReadDrawable),
3037   GLX_FUNCTION(glXGetFBConfigAttrib),
3038   GLX_FUNCTION(glXGetFBConfigs),
3039   GLX_FUNCTION(glXGetSelectedEvent),
3040   GLX_FUNCTION(glXGetVisualFromFBConfig),
3041   GLX_FUNCTION(glXMakeContextCurrent),
3042   GLX_FUNCTION(glXQueryContext),
3043   GLX_FUNCTION(glXQueryDrawable),
3044   GLX_FUNCTION(glXSelectEvent),
3045
3046   /*** GLX_SGI_swap_control ***/
3047   GLX_FUNCTION2(glXSwapIntervalSGI, __glXSwapIntervalSGI),
3048
3049   /*** GLX_SGI_video_sync ***/
3050   GLX_FUNCTION2(glXGetVideoSyncSGI, __glXGetVideoSyncSGI),
3051   GLX_FUNCTION2(glXWaitVideoSyncSGI, __glXWaitVideoSyncSGI),
3052
3053   /*** GLX_SGI_make_current_read ***/
3054   GLX_FUNCTION2(glXMakeCurrentReadSGI, glXMakeContextCurrent),
3055   GLX_FUNCTION2(glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable),
3056
3057   /*** GLX_EXT_import_context ***/
3058   GLX_FUNCTION(glXFreeContextEXT),
3059   GLX_FUNCTION(glXGetContextIDEXT),
3060   GLX_FUNCTION2(glXGetCurrentDisplayEXT, glXGetCurrentDisplay),
3061   GLX_FUNCTION(glXImportContextEXT),
3062   GLX_FUNCTION2(glXQueryContextInfoEXT, glXQueryContext),
3063
3064   /*** GLX_SGIX_fbconfig ***/
3065   GLX_FUNCTION2(glXGetFBConfigAttribSGIX, glXGetFBConfigAttrib),
3066   GLX_FUNCTION2(glXChooseFBConfigSGIX, glXChooseFBConfig),
3067   GLX_FUNCTION(glXCreateGLXPixmapWithConfigSGIX),
3068   GLX_FUNCTION(glXCreateContextWithConfigSGIX),
3069   GLX_FUNCTION2(glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig),
3070   GLX_FUNCTION(glXGetFBConfigFromVisualSGIX),
3071
3072   /*** GLX_SGIX_pbuffer ***/
3073   GLX_FUNCTION(glXCreateGLXPbufferSGIX),
3074   GLX_FUNCTION(glXDestroyGLXPbufferSGIX),
3075   GLX_FUNCTION(glXQueryGLXPbufferSGIX),
3076   GLX_FUNCTION(glXSelectEventSGIX),
3077   GLX_FUNCTION(glXGetSelectedEventSGIX),
3078
3079   /*** GLX_SGIX_swap_group ***/
3080   GLX_FUNCTION2(glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX),
3081
3082   /*** GLX_SGIX_swap_barrier ***/
3083   GLX_FUNCTION2(glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX),
3084   GLX_FUNCTION2(glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX),
3085
3086   /*** GLX_MESA_allocate_memory ***/
3087   GLX_FUNCTION(glXAllocateMemoryMESA),
3088   GLX_FUNCTION(glXFreeMemoryMESA),
3089   GLX_FUNCTION(glXGetMemoryOffsetMESA),
3090
3091   /*** GLX_MESA_copy_sub_buffer ***/
3092   GLX_FUNCTION2(glXCopySubBufferMESA, __glXCopySubBufferMESA),
3093
3094   /*** GLX_MESA_pixmap_colormap ***/
3095   GLX_FUNCTION(glXCreateGLXPixmapMESA),
3096
3097   /*** GLX_MESA_release_buffers ***/
3098   GLX_FUNCTION2(glXReleaseBuffersMESA, __glXReleaseBuffersMESA),
3099
3100   /*** GLX_MESA_swap_control ***/
3101   GLX_FUNCTION2(glXSwapIntervalMESA, __glXSwapIntervalMESA),
3102   GLX_FUNCTION2(glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA),
3103
3104   /*** GLX_MESA_swap_frame_usage ***/
3105   GLX_FUNCTION2(glXBeginFrameTrackingMESA, __glXBeginFrameTrackingMESA),
3106   GLX_FUNCTION2(glXEndFrameTrackingMESA, __glXEndFrameTrackingMESA),
3107   GLX_FUNCTION2(glXGetFrameUsageMESA, __glXGetFrameUsageMESA),
3108   GLX_FUNCTION2(glXQueryFrameTrackingMESA, __glXQueryFrameTrackingMESA),
3109
3110   /*** GLX_ARB_get_proc_address ***/
3111   GLX_FUNCTION(glXGetProcAddressARB),
3112
3113   /*** GLX 1.4 ***/
3114   GLX_FUNCTION2(glXGetProcAddress, glXGetProcAddressARB),
3115
3116   /*** GLX_OML_sync_control ***/
3117   GLX_FUNCTION2(glXWaitForSbcOML, __glXWaitForSbcOML),
3118   GLX_FUNCTION2(glXWaitForMscOML, __glXWaitForMscOML),
3119   GLX_FUNCTION2(glXSwapBuffersMscOML, __glXSwapBuffersMscOML),
3120   GLX_FUNCTION2(glXGetMscRateOML, __glXGetMscRateOML),
3121   GLX_FUNCTION2(glXGetSyncValuesOML, __glXGetSyncValuesOML),
3122
3123   /*** GLX_EXT_texture_from_pixmap ***/
3124   GLX_FUNCTION2(glXBindTexImageEXT, __glXBindTexImageEXT),
3125   GLX_FUNCTION2(glXReleaseTexImageEXT, __glXReleaseTexImageEXT),
3126
3127#ifdef GLX_DIRECT_RENDERING
3128   /*** DRI configuration ***/
3129   GLX_FUNCTION(glXGetScreenDriver),
3130   GLX_FUNCTION(glXGetDriverConfig),
3131#endif
3132
3133   {NULL, NULL}                 /* end of list */
3134};
3135
3136
3137static const GLvoid *
3138get_glx_proc_address(const char *funcName)
3139{
3140   GLuint i;
3141
3142   /* try static functions */
3143   for (i = 0; GLX_functions[i].Name; i++) {
3144      if (strcmp(GLX_functions[i].Name, funcName) == 0)
3145         return GLX_functions[i].Address;
3146   }
3147
3148   return NULL;
3149}
3150
3151
3152/**
3153 * Get the address of a named GL function.  This is the pre-GLX 1.4 name for
3154 * \c glXGetProcAddress.
3155 *
3156 * \param procName  Name of a GL or GLX function.
3157 * \returns         A pointer to the named function
3158 *
3159 * \sa glXGetProcAddress
3160 */
3161PUBLIC void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
3162{
3163   typedef void (*gl_function) (void);
3164   gl_function f;
3165
3166
3167   /* Search the table of GLX and internal functions first.  If that
3168    * fails and the supplied name could be a valid core GL name, try
3169    * searching the core GL function table.  This check is done to prevent
3170    * DRI based drivers from searching the core GL function table for
3171    * internal API functions.
3172    */
3173
3174   f = (gl_function) get_glx_proc_address((const char *) procName);
3175   if ((f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
3176       && (procName[2] != 'X')) {
3177      f = (gl_function) _glapi_get_proc_address((const char *) procName);
3178   }
3179
3180   return f;
3181}
3182
3183/**
3184 * Get the address of a named GL function.  This is the GLX 1.4 name for
3185 * \c glXGetProcAddressARB.
3186 *
3187 * \param procName  Name of a GL or GLX function.
3188 * \returns         A pointer to the named function
3189 *
3190 * \sa glXGetProcAddressARB
3191 */
3192PUBLIC void (*glXGetProcAddress(const GLubyte * procName)) (void)
3193#if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
3194   __attribute__ ((alias("glXGetProcAddressARB")));
3195#else
3196{
3197   return glXGetProcAddressARB(procName);
3198}
3199#endif /* __GNUC__ */
3200
3201
3202#ifdef GLX_DIRECT_RENDERING
3203/**
3204 * Get the unadjusted system time (UST).  Currently, the UST is measured in
3205 * microseconds since Epoc.  The actual resolution of the UST may vary from
3206 * system to system, and the units may vary from release to release.
3207 * Drivers should not call this function directly.  They should instead use
3208 * \c glXGetProcAddress to obtain a pointer to the function.
3209 *
3210 * \param ust Location to store the 64-bit UST
3211 * \returns Zero on success or a negative errno value on failure.
3212 *
3213 * \sa glXGetProcAddress, PFNGLXGETUSTPROC
3214 *
3215 * \since Internal API version 20030317.
3216 */
3217_X_HIDDEN int
3218__glXGetUST(int64_t * ust)
3219{
3220   struct timeval tv;
3221
3222   if (ust == NULL) {
3223      return -EFAULT;
3224   }
3225
3226   if (gettimeofday(&tv, NULL) == 0) {
3227      ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
3228      return 0;
3229   }
3230   else {
3231      return -errno;
3232   }
3233}
3234#endif /* GLX_DIRECT_RENDERING */
3235