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