OSDN Git Service

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