OSDN Git Service

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