OSDN Git Service

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