glxapi.c revision 7cd2ae9d97377bc68f66ce3c7734f56e3f5dfa6b
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.3
4 *
5 * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * 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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26/*
27 * This is the GLX API dispatcher.  Calls to the glX* functions are
28 * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions.
29 * See the glxapi.h file for more details.
30 */
31
32
33#include <assert.h>
34#include <stdlib.h>
35#include <stdio.h>
36#include <string.h>
37#include "glheader.h"
38#include "glapi.h"
39#include "glxapi.h"
40
41
42extern struct _glxapi_table *_real_GetGLXDispatchTable(void);
43extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
44
45
46struct display_dispatch {
47   Display *Dpy;
48   struct _glxapi_table *Table;
49   struct display_dispatch *Next;
50};
51
52static struct display_dispatch *DispatchList = NULL;
53
54
55/* Display -> Dispatch caching */
56static Display *prevDisplay = NULL;
57static struct _glxapi_table *prevTable = NULL;
58
59
60static struct _glxapi_table *
61get_dispatch(Display *dpy)
62{
63   if (!dpy)
64      return NULL;
65
66   /* search list of display/dispatch pairs for this display */
67   {
68      const struct display_dispatch *d = DispatchList;
69      while (d) {
70         if (d->Dpy == dpy) {
71            prevDisplay = dpy;
72            prevTable = d->Table;
73            return d->Table;  /* done! */
74         }
75         d = d->Next;
76      }
77   }
78
79   /* A new display, determine if we should use real GLX
80    * or Mesa's pseudo-GLX.
81    */
82   {
83      struct _glxapi_table *t = NULL;
84
85#ifdef GLX_BUILT_IN_XMESA
86      if (!getenv("LIBGL_FORCE_XMESA")) {
87         int ignore;
88         if (XQueryExtension( dpy, "GLX", &ignore, &ignore, &ignore )) {
89            /* the X server has the GLX extension */
90            t = _real_GetGLXDispatchTable();
91         }
92      }
93#endif
94
95      if (!t) {
96         /* Fallback to Mesa with Xlib driver */
97#ifdef GLX_BUILT_IN_XMESA
98         if (getenv("LIBGL_DEBUG")) {
99            fprintf(stderr,
100                    "libGL: server %s lacks the GLX extension.",
101                    dpy->display_name);
102            fprintf(stderr, " Using Mesa Xlib renderer.\n");
103         }
104#endif
105         t = _mesa_GetGLXDispatchTable();
106         assert(t);  /* this has to work */
107      }
108
109      if (t) {
110         struct display_dispatch *d;
111         d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch));
112         if (d) {
113            d->Dpy = dpy;
114            d->Table = t;
115            /* insert at head of list */
116            d->Next = DispatchList;
117            DispatchList = d;
118            /* update cache */
119            prevDisplay = dpy;
120            prevTable = t;
121            return t;
122         }
123      }
124   }
125
126   /* If we get here that means we can't use real GLX on this display
127    * and the Mesa pseudo-GLX software renderer wasn't compiled in.
128    * Or, we ran out of memory!
129    */
130   return NULL;
131}
132
133
134#define GET_DISPATCH(DPY, TABLE)	\
135   if (DPY == prevDisplay) {		\
136      TABLE = prevTable;		\
137   }					\
138   else if (!DPY) {			\
139      TABLE = NULL;			\
140   }					\
141   else {				\
142      TABLE = get_dispatch(DPY);	\
143   }
144
145
146
147
148/* Set by glXMakeCurrent() and glXMakeContextCurrent() only */
149#ifndef GLX_BUILT_IN_XMESA
150static GLXContext CurrentContext = 0;
151#define __glXGetCurrentContext() CurrentContext;
152#endif
153
154
155/*
156 * GLX API entrypoints
157 */
158
159/*** GLX_VERSION_1_0 ***/
160
161XVisualInfo PUBLIC *
162glXChooseVisual(Display *dpy, int screen, int *list)
163{
164   struct _glxapi_table *t;
165   GET_DISPATCH(dpy, t);
166   if (!t)
167      return NULL;
168   return (t->ChooseVisual)(dpy, screen, list);
169}
170
171
172void PUBLIC
173glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask)
174{
175   struct _glxapi_table *t;
176   GET_DISPATCH(dpy, t);
177   if (!t)
178      return;
179   (t->CopyContext)(dpy, src, dst, mask);
180}
181
182
183GLXContext PUBLIC
184glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct)
185{
186   struct _glxapi_table *t;
187   GET_DISPATCH(dpy, t);
188   if (!t)
189      return 0;
190   return (t->CreateContext)(dpy, visinfo, shareList, direct);
191}
192
193
194GLXPixmap PUBLIC
195glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap)
196{
197   struct _glxapi_table *t;
198   GET_DISPATCH(dpy, t);
199   if (!t)
200      return 0;
201   return (t->CreateGLXPixmap)(dpy, visinfo, pixmap);
202}
203
204
205void PUBLIC
206glXDestroyContext(Display *dpy, GLXContext ctx)
207{
208   struct _glxapi_table *t;
209   GET_DISPATCH(dpy, t);
210   if (!t)
211      return;
212   (t->DestroyContext)(dpy, ctx);
213}
214
215
216void PUBLIC
217glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap)
218{
219   struct _glxapi_table *t;
220   GET_DISPATCH(dpy, t);
221   if (!t)
222      return;
223   (t->DestroyGLXPixmap)(dpy, pixmap);
224}
225
226
227int PUBLIC
228glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value)
229{
230   struct _glxapi_table *t;
231   GET_DISPATCH(dpy, t);
232   if (!t)
233      return GLX_NO_EXTENSION;
234   return (t->GetConfig)(dpy, visinfo, attrib, value);
235}
236
237
238#ifdef GLX_BUILT_IN_XMESA
239/* Use real libGL's glXGetCurrentContext() function */
240#else
241/* stand-alone Mesa */
242GLXContext PUBLIC
243glXGetCurrentContext(void)
244{
245   return CurrentContext;
246}
247#endif
248
249
250#ifdef GLX_BUILT_IN_XMESA
251/* Use real libGL's glXGetCurrentContext() function */
252#else
253/* stand-alone Mesa */
254GLXDrawable PUBLIC
255glXGetCurrentDrawable(void)
256{
257   __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
258   return gc ? gc->currentDrawable : 0;
259}
260#endif
261
262
263Bool PUBLIC
264glXIsDirect(Display *dpy, GLXContext ctx)
265{
266   struct _glxapi_table *t;
267   GET_DISPATCH(dpy, t);
268   if (!t)
269      return False;
270   return (t->IsDirect)(dpy, ctx);
271}
272
273
274Bool PUBLIC
275glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
276{
277   Bool b;
278   struct _glxapi_table *t;
279   GET_DISPATCH(dpy, t);
280   if (!t) {
281      return False;
282   }
283   b = (*t->MakeCurrent)(dpy, drawable, ctx);
284#ifndef  GLX_BUILT_IN_XMESA
285   if (b) {
286      CurrentContext = ctx;
287   }
288#endif
289   return b;
290}
291
292
293Bool PUBLIC
294glXQueryExtension(Display *dpy, int *errorb, int *event)
295{
296   struct _glxapi_table *t;
297   GET_DISPATCH(dpy, t);
298   if (!t)
299      return False;
300   return (t->QueryExtension)(dpy, errorb, event);
301}
302
303
304Bool PUBLIC
305glXQueryVersion(Display *dpy, int *maj, int *min)
306{
307   struct _glxapi_table *t;
308   GET_DISPATCH(dpy, t);
309   if (!t)
310      return False;
311   return (t->QueryVersion)(dpy, maj, min);
312}
313
314
315void PUBLIC
316glXSwapBuffers(Display *dpy, GLXDrawable drawable)
317{
318   struct _glxapi_table *t;
319   GET_DISPATCH(dpy, t);
320   if (!t)
321      return;
322   (t->SwapBuffers)(dpy, drawable);
323}
324
325
326void PUBLIC
327glXUseXFont(Font font, int first, int count, int listBase)
328{
329   struct _glxapi_table *t;
330   Display *dpy = glXGetCurrentDisplay();
331   GET_DISPATCH(dpy, t);
332   if (!t)
333      return;
334   (t->UseXFont)(font, first, count, listBase);
335}
336
337
338void PUBLIC
339glXWaitGL(void)
340{
341   struct _glxapi_table *t;
342   Display *dpy = glXGetCurrentDisplay();
343   GET_DISPATCH(dpy, t);
344   if (!t)
345      return;
346   (t->WaitGL)();
347}
348
349
350void PUBLIC
351glXWaitX(void)
352{
353   struct _glxapi_table *t;
354   Display *dpy = glXGetCurrentDisplay();
355   GET_DISPATCH(dpy, t);
356   if (!t)
357      return;
358   (t->WaitX)();
359}
360
361
362
363/*** GLX_VERSION_1_1 ***/
364
365const char PUBLIC *
366glXGetClientString(Display *dpy, int name)
367{
368   struct _glxapi_table *t;
369   GET_DISPATCH(dpy, t);
370   if (!t)
371      return NULL;
372   return (t->GetClientString)(dpy, name);
373}
374
375
376const char PUBLIC *
377glXQueryExtensionsString(Display *dpy, int screen)
378{
379   struct _glxapi_table *t;
380   GET_DISPATCH(dpy, t);
381   if (!t)
382      return NULL;
383   return (t->QueryExtensionsString)(dpy, screen);
384}
385
386
387const char PUBLIC *
388glXQueryServerString(Display *dpy, int screen, int name)
389{
390   struct _glxapi_table *t;
391   GET_DISPATCH(dpy, t);
392   if (!t)
393      return NULL;
394   return (t->QueryServerString)(dpy, screen, name);
395}
396
397
398/*** GLX_VERSION_1_2 ***/
399
400#if !defined(GLX_BUILT_IN_XMESA)
401Display PUBLIC *
402glXGetCurrentDisplay(void)
403{
404   /* Same code as in libGL's glxext.c */
405   __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
406   if (NULL == gc) return NULL;
407   return gc->currentDpy;
408}
409#endif
410
411
412
413/*** GLX_VERSION_1_3 ***/
414
415GLXFBConfig PUBLIC *
416glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems)
417{
418   struct _glxapi_table *t;
419   GET_DISPATCH(dpy, t);
420   if (!t)
421      return 0;
422   return (t->ChooseFBConfig)(dpy, screen, attribList, nitems);
423}
424
425
426GLXContext PUBLIC
427glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct)
428{
429   struct _glxapi_table *t;
430   GET_DISPATCH(dpy, t);
431   if (!t)
432      return 0;
433   return (t->CreateNewContext)(dpy, config, renderType, shareList, direct);
434}
435
436
437GLXPbuffer PUBLIC
438glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
439{
440   struct _glxapi_table *t;
441   GET_DISPATCH(dpy, t);
442   if (!t)
443      return 0;
444   return (t->CreatePbuffer)(dpy, config, attribList);
445}
446
447
448GLXPixmap PUBLIC
449glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList)
450{
451   struct _glxapi_table *t;
452   GET_DISPATCH(dpy, t);
453   if (!t)
454      return 0;
455   return (t->CreatePixmap)(dpy, config, pixmap, attribList);
456}
457
458
459GLXWindow PUBLIC
460glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList)
461{
462   struct _glxapi_table *t;
463   GET_DISPATCH(dpy, t);
464   if (!t)
465      return 0;
466   return (t->CreateWindow)(dpy, config, win, attribList);
467}
468
469
470void PUBLIC
471glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
472{
473   struct _glxapi_table *t;
474   GET_DISPATCH(dpy, t);
475   if (!t)
476      return;
477   (t->DestroyPbuffer)(dpy, pbuf);
478}
479
480
481void PUBLIC
482glXDestroyPixmap(Display *dpy, GLXPixmap pixmap)
483{
484   struct _glxapi_table *t;
485   GET_DISPATCH(dpy, t);
486   if (!t)
487      return;
488   (t->DestroyPixmap)(dpy, pixmap);
489}
490
491
492void PUBLIC
493glXDestroyWindow(Display *dpy, GLXWindow window)
494{
495   struct _glxapi_table *t;
496   GET_DISPATCH(dpy, t);
497   if (!t)
498      return;
499   (t->DestroyWindow)(dpy, window);
500}
501
502
503#ifdef GLX_BUILT_IN_XMESA
504/* Use the glXGetCurrentReadDrawable() function from libGL */
505#else
506GLXDrawable PUBLIC
507glXGetCurrentReadDrawable(void)
508{
509   __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
510   return gc ? gc->currentReadable : 0;
511}
512#endif
513
514
515int PUBLIC
516glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value)
517{
518   struct _glxapi_table *t;
519   GET_DISPATCH(dpy, t);
520   if (!t)
521      return GLX_NO_EXTENSION;
522   return (t->GetFBConfigAttrib)(dpy, config, attribute, value);
523}
524
525
526GLXFBConfig PUBLIC *
527glXGetFBConfigs(Display *dpy, int screen, int *nelements)
528{
529   struct _glxapi_table *t;
530   GET_DISPATCH(dpy, t);
531   if (!t)
532      return 0;
533   return (t->GetFBConfigs)(dpy, screen, nelements);
534}
535
536void PUBLIC
537glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
538{
539   struct _glxapi_table *t;
540   GET_DISPATCH(dpy, t);
541   if (!t)
542      return;
543   (t->GetSelectedEvent)(dpy, drawable, mask);
544}
545
546
547XVisualInfo PUBLIC *
548glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
549{
550   struct _glxapi_table *t;
551   GET_DISPATCH(dpy, t);
552   if (!t)
553      return NULL;
554   return (t->GetVisualFromFBConfig)(dpy, config);
555}
556
557
558Bool PUBLIC
559glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
560{
561   Bool b;
562   struct _glxapi_table *t;
563   GET_DISPATCH(dpy, t);
564   if (!t)
565      return False;
566   b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
567#ifndef GLX_BUILT_IN_XMESA
568   if (b) {
569      CurrentContext = ctx;
570   }
571#endif
572   return b;
573}
574
575
576int PUBLIC
577glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
578{
579   struct _glxapi_table *t;
580   GET_DISPATCH(dpy, t);
581   assert(t);
582   if (!t)
583      return 0; /* XXX correct? */
584   return (t->QueryContext)(dpy, ctx, attribute, value);
585}
586
587
588void PUBLIC
589glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
590{
591   struct _glxapi_table *t;
592   GET_DISPATCH(dpy, t);
593   if (!t)
594      return;
595   (t->QueryDrawable)(dpy, draw, attribute, value);
596}
597
598
599void PUBLIC
600glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
601{
602   struct _glxapi_table *t;
603   GET_DISPATCH(dpy, t);
604   if (!t)
605      return;
606   (t->SelectEvent)(dpy, drawable, mask);
607}
608
609
610
611/*** GLX_SGI_swap_control ***/
612
613int PUBLIC
614glXSwapIntervalSGI(int interval)
615{
616   struct _glxapi_table *t;
617   Display *dpy = glXGetCurrentDisplay();
618   GET_DISPATCH(dpy, t);
619   if (!t)
620      return 0;
621   return (t->SwapIntervalSGI)(interval);
622}
623
624
625
626/*** GLX_SGI_video_sync ***/
627
628int PUBLIC
629glXGetVideoSyncSGI(unsigned int *count)
630{
631   struct _glxapi_table *t;
632   Display *dpy = glXGetCurrentDisplay();
633   GET_DISPATCH(dpy, t);
634   if (!t)
635      return 0;
636   return (t->GetVideoSyncSGI)(count);
637}
638
639int PUBLIC
640glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
641{
642   struct _glxapi_table *t;
643   Display *dpy = glXGetCurrentDisplay();
644   GET_DISPATCH(dpy, t);
645   if (!t)
646      return 0;
647   return (t->WaitVideoSyncSGI)(divisor, remainder, count);
648}
649
650
651
652/*** GLX_SGI_make_current_read ***/
653
654Bool PUBLIC
655glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
656{
657   struct _glxapi_table *t;
658   GET_DISPATCH(dpy, t);
659   if (!t)
660      return 0;
661   return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx);
662}
663
664#ifdef GLX_BUILT_IN_XMESA
665/* Use glXGetCurrentReadDrawableSGI() from libGL */
666#else
667/* stand-alone Mesa */
668GLXDrawable PUBLIC
669glXGetCurrentReadDrawableSGI(void)
670{
671   return glXGetCurrentReadDrawable();
672}
673#endif
674
675
676#if defined(_VL_H)
677
678GLXVideoSourceSGIX PUBLIC
679glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
680{
681   struct _glxapi_table *t;
682   GET_DISPATCH(dpy, t);
683   if (!t)
684      return 0;
685   return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode);
686}
687
688void PUBLIC
689glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
690{
691   struct _glxapi_table *t;
692   GET_DISPATCH(dpy, t);
693   if (!t)
694      return 0;
695   return (t->DestroyGLXVideoSourceSGIX)(dpy, src);
696}
697
698#endif
699
700
701/*** GLX_EXT_import_context ***/
702
703void PUBLIC
704glXFreeContextEXT(Display *dpy, GLXContext context)
705{
706   struct _glxapi_table *t;
707   GET_DISPATCH(dpy, t);
708   if (!t)
709      return;
710   (t->FreeContextEXT)(dpy, context);
711}
712
713#ifdef GLX_BUILT_IN_XMESA
714/* Use real libGL's glXGetContextIDEXT() function */
715#else
716/* stand-alone Mesa */
717GLXContextID PUBLIC
718glXGetContextIDEXT(const GLXContext context)
719{
720   return ((__GLXcontext *) context)->xid;
721}
722#endif
723
724#ifdef GLX_BUILT_IN_XMESA
725/* Use real libGL's glXGetCurrentDisplayEXT() function */
726#else
727/* stand-alone Mesa */
728Display PUBLIC *
729glXGetCurrentDisplayEXT(void)
730{
731   return glXGetCurrentDisplay();
732}
733#endif
734
735GLXContext PUBLIC
736glXImportContextEXT(Display *dpy, GLXContextID contextID)
737{
738   struct _glxapi_table *t;
739   GET_DISPATCH(dpy, t);
740   if (!t)
741      return 0;
742   return (t->ImportContextEXT)(dpy, contextID);
743}
744
745int PUBLIC
746glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value)
747{
748   struct _glxapi_table *t;
749   GET_DISPATCH(dpy, t);
750   if (!t)
751      return 0;  /* XXX ok? */
752   return (t->QueryContextInfoEXT)(dpy, context, attribute, value);
753}
754
755
756
757/*** GLX_SGIX_fbconfig ***/
758
759int PUBLIC
760glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
761{
762   struct _glxapi_table *t;
763   GET_DISPATCH(dpy, t);
764   if (!t)
765      return 0;
766   return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value);
767}
768
769GLXFBConfigSGIX PUBLIC *
770glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
771{
772   struct _glxapi_table *t;
773   GET_DISPATCH(dpy, t);
774   if (!t)
775      return 0;
776   return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements);
777}
778
779GLXPixmap PUBLIC
780glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
781{
782   struct _glxapi_table *t;
783   GET_DISPATCH(dpy, t);
784   if (!t)
785      return 0;
786   return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap);
787}
788
789GLXContext PUBLIC
790glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
791{
792   struct _glxapi_table *t;
793   GET_DISPATCH(dpy, t);
794   if (!t)
795      return 0;
796   return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct);
797}
798
799XVisualInfo PUBLIC *
800glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
801{
802   struct _glxapi_table *t;
803   GET_DISPATCH(dpy, t);
804   if (!t)
805      return 0;
806   return (t->GetVisualFromFBConfigSGIX)(dpy, config);
807}
808
809GLXFBConfigSGIX PUBLIC
810glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
811{
812   struct _glxapi_table *t;
813   GET_DISPATCH(dpy, t);
814   if (!t)
815      return 0;
816   return (t->GetFBConfigFromVisualSGIX)(dpy, vis);
817}
818
819
820
821/*** GLX_SGIX_pbuffer ***/
822
823GLXPbufferSGIX PUBLIC
824glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
825{
826   struct _glxapi_table *t;
827   GET_DISPATCH(dpy, t);
828   if (!t)
829      return 0;
830   return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list);
831}
832
833void PUBLIC
834glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
835{
836   struct _glxapi_table *t;
837   GET_DISPATCH(dpy, t);
838   if (!t)
839      return;
840   (t->DestroyGLXPbufferSGIX)(dpy, pbuf);
841}
842
843int PUBLIC
844glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
845{
846   struct _glxapi_table *t;
847   GET_DISPATCH(dpy, t);
848   if (!t)
849      return 0;
850   return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value);
851}
852
853void PUBLIC
854glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
855{
856   struct _glxapi_table *t;
857   GET_DISPATCH(dpy, t);
858   if (!t)
859      return;
860   (t->SelectEventSGIX)(dpy, drawable, mask);
861}
862
863void PUBLIC
864glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
865{
866   struct _glxapi_table *t;
867   GET_DISPATCH(dpy, t);
868   if (!t)
869      return;
870   (t->GetSelectedEventSGIX)(dpy, drawable, mask);
871}
872
873
874
875/*** GLX_SGI_cushion ***/
876
877void PUBLIC
878glXCushionSGI(Display *dpy, Window win, float cushion)
879{
880   struct _glxapi_table *t;
881   GET_DISPATCH(dpy, t);
882   if (!t)
883      return;
884   (t->CushionSGI)(dpy, win, cushion);
885}
886
887
888
889/*** GLX_SGIX_video_resize ***/
890
891int PUBLIC
892glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
893{
894   struct _glxapi_table *t;
895   GET_DISPATCH(dpy, t);
896   if (!t)
897      return 0;
898   return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window);
899}
900
901int PUBLIC
902glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
903{
904   struct _glxapi_table *t;
905   GET_DISPATCH(dpy, t);
906   if (!t)
907      return 0;
908   return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
909}
910
911int PUBLIC
912glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
913{
914   struct _glxapi_table *t;
915   GET_DISPATCH(dpy, t);
916   if (!t)
917      return 0;
918   return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
919}
920
921int PUBLIC
922glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
923{
924   struct _glxapi_table *t;
925   GET_DISPATCH(dpy, t);
926   if (!t)
927      return 0;
928   return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh);
929}
930
931int PUBLIC
932glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
933{
934   struct _glxapi_table *t;
935   GET_DISPATCH(dpy, t);
936   if (!t)
937      return 0;
938   return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype);
939}
940
941
942
943#if defined(_DM_BUFFER_H_)
944
945Bool PUBLIC
946glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
947{
948   struct _glxapi_table *t;
949   GET_DISPATCH(dpy, t);
950   if (!t)
951      return False;
952   return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer);
953}
954
955#endif
956
957
958/*** GLX_SGIX_swap_group ***/
959
960void PUBLIC
961glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
962{
963   struct _glxapi_table *t;
964   GET_DISPATCH(dpy, t);
965   if (!t)
966      return;
967   (*t->JoinSwapGroupSGIX)(dpy, drawable, member);
968}
969
970
971/*** GLX_SGIX_swap_barrier ***/
972
973void PUBLIC
974glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
975{
976   struct _glxapi_table *t;
977   GET_DISPATCH(dpy, t);
978   if (!t)
979      return;
980   (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier);
981}
982
983Bool PUBLIC
984glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
985{
986   struct _glxapi_table *t;
987   GET_DISPATCH(dpy, t);
988   if (!t)
989      return False;
990   return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max);
991}
992
993
994
995/*** GLX_SUN_get_transparent_index ***/
996
997Status PUBLIC
998glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
999{
1000   struct _glxapi_table *t;
1001   GET_DISPATCH(dpy, t);
1002   if (!t)
1003      return False;
1004   return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent);
1005}
1006
1007
1008
1009/*** GLX_MESA_copy_sub_buffer ***/
1010
1011void PUBLIC
1012glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height)
1013{
1014   struct _glxapi_table *t;
1015   GET_DISPATCH(dpy, t);
1016   if (!t)
1017      return;
1018   (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height);
1019}
1020
1021
1022
1023/*** GLX_MESA_release_buffers ***/
1024
1025Bool PUBLIC
1026glXReleaseBuffersMESA(Display *dpy, Window w)
1027{
1028   struct _glxapi_table *t;
1029   GET_DISPATCH(dpy, t);
1030   if (!t)
1031      return False;
1032   return (t->ReleaseBuffersMESA)(dpy, w);
1033}
1034
1035
1036
1037/*** GLX_MESA_pixmap_colormap ***/
1038
1039GLXPixmap PUBLIC
1040glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap)
1041{
1042   struct _glxapi_table *t;
1043   GET_DISPATCH(dpy, t);
1044   if (!t)
1045      return 0;
1046   return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap);
1047}
1048
1049
1050
1051/*** GLX_MESA_set_3dfx_mode ***/
1052
1053Bool PUBLIC
1054glXSet3DfxModeMESA(int mode)
1055{
1056   struct _glxapi_table *t;
1057   Display *dpy = glXGetCurrentDisplay();
1058   GET_DISPATCH(dpy, t);
1059   if (!t)
1060      return False;
1061   return (t->Set3DfxModeMESA)(mode);
1062}
1063
1064
1065
1066/*** GLX_NV_vertex_array_range ***/
1067
1068void PUBLIC *
1069glXAllocateMemoryNV( GLsizei size,
1070                     GLfloat readFrequency,
1071                     GLfloat writeFrequency,
1072                     GLfloat priority )
1073{
1074   struct _glxapi_table *t;
1075   Display *dpy = glXGetCurrentDisplay();
1076   GET_DISPATCH(dpy, t);
1077   if (!t)
1078      return NULL;
1079   return (t->AllocateMemoryNV)(size, readFrequency, writeFrequency, priority);
1080}
1081
1082
1083void PUBLIC
1084glXFreeMemoryNV( GLvoid *pointer )
1085{
1086   struct _glxapi_table *t;
1087   Display *dpy = glXGetCurrentDisplay();
1088   GET_DISPATCH(dpy, t);
1089   if (!t)
1090      return;
1091   (t->FreeMemoryNV)(pointer);
1092}
1093
1094
1095
1096
1097/*** GLX_MESA_agp_offset */
1098
1099GLuint PUBLIC
1100glXGetAGPOffsetMESA( const GLvoid *pointer )
1101{
1102   struct _glxapi_table *t;
1103   Display *dpy = glXGetCurrentDisplay();
1104   GET_DISPATCH(dpy, t);
1105   if (!t)
1106      return ~0;
1107   return (t->GetAGPOffsetMESA)(pointer);
1108}
1109
1110
1111/*** GLX_MESA_allocate_memory */
1112
1113void *
1114glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size,
1115                      float readfreq, float writefreq, float priority)
1116{
1117   /* dummy */
1118   return NULL;
1119}
1120
1121void
1122glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
1123{
1124   /* dummy */
1125}
1126
1127
1128GLuint
1129glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer)
1130{
1131   /* dummy */
1132   return 0;
1133}
1134
1135
1136
1137/**********************************************************************/
1138/* GLX API management functions                                       */
1139/**********************************************************************/
1140
1141
1142const char *
1143_glxapi_get_version(void)
1144{
1145   return "1.3";
1146}
1147
1148
1149/*
1150 * Return array of extension strings.
1151 */
1152const char **
1153_glxapi_get_extensions(void)
1154{
1155   static const char *extensions[] = {
1156#ifdef GLX_EXT_import_context
1157      "GLX_EXT_import_context",
1158#endif
1159#ifdef GLX_SGI_video_sync
1160      "GLX_SGI_video_sync",
1161#endif
1162#ifdef GLX_MESA_copy_sub_buffer
1163      "GLX_MESA_copy_sub_buffer",
1164#endif
1165#ifdef GLX_MESA_release_buffers
1166      "GLX_MESA_release_buffers",
1167#endif
1168#ifdef GLX_MESA_pixmap_colormap
1169      "GLX_MESA_pixmap_colormap",
1170#endif
1171#ifdef GLX_MESA_set_3dfx_mode
1172      "GLX_MESA_set_3dfx_mode",
1173#endif
1174#ifdef GLX_SGIX_fbconfig
1175      "GLX_SGIX_fbconfig",
1176#endif
1177#ifdef GLX_SGIX_pbuffer
1178      "GLX_SGIX_pbuffer",
1179#endif
1180      NULL
1181   };
1182   return extensions;
1183}
1184
1185
1186/*
1187 * Return size of the GLX dispatch table, in entries, not bytes.
1188 */
1189GLuint
1190_glxapi_get_dispatch_table_size(void)
1191{
1192   return sizeof(struct _glxapi_table) / sizeof(void *);
1193}
1194
1195
1196static int
1197generic_no_op_func(void)
1198{
1199   return 0;
1200}
1201
1202
1203/*
1204 * Initialize all functions in given dispatch table to be no-ops
1205 */
1206void
1207_glxapi_set_no_op_table(struct _glxapi_table *t)
1208{
1209   typedef int (*nop_func)(void);
1210   nop_func *dispatch = (nop_func *) t;
1211   GLuint n = _glxapi_get_dispatch_table_size();
1212   GLuint i;
1213   for (i = 0; i < n; i++) {
1214      dispatch[i] = generic_no_op_func;
1215   }
1216}
1217
1218
1219struct name_address_pair {
1220   const char *Name;
1221   __GLXextFuncPtr Address;
1222};
1223
1224static struct name_address_pair GLX_functions[] = {
1225   /*** GLX_VERSION_1_0 ***/
1226   { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual },
1227   { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext },
1228   { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext },
1229   { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap },
1230   { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext },
1231   { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap },
1232   { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig },
1233   { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext },
1234   { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable },
1235   { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect },
1236   { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent },
1237   { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension },
1238   { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion },
1239   { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers },
1240   { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont },
1241   { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL },
1242   { "glXWaitX", (__GLXextFuncPtr) glXWaitX },
1243
1244   /*** GLX_VERSION_1_1 ***/
1245   { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString },
1246   { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString },
1247   { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString },
1248
1249   /*** GLX_VERSION_1_2 ***/
1250   { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay },
1251
1252   /*** GLX_VERSION_1_3 ***/
1253   { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig },
1254   { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext },
1255   { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer },
1256   { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap },
1257   { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow },
1258   { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer },
1259   { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap },
1260   { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow },
1261   { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable },
1262   { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib },
1263   { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs },
1264   { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent },
1265   { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig },
1266   { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent },
1267   { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext },
1268   { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable },
1269   { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent },
1270
1271   /*** GLX_VERSION_1_4 ***/
1272   { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress },
1273
1274   /*** GLX_SGI_swap_control ***/
1275   { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI },
1276
1277   /*** GLX_SGI_video_sync ***/
1278   { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI },
1279   { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI },
1280
1281   /*** GLX_SGI_make_current_read ***/
1282   { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI },
1283   { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI },
1284
1285   /*** GLX_SGIX_video_source ***/
1286#if defined(_VL_H)
1287   { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX },
1288   { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX },
1289#endif
1290
1291   /*** GLX_EXT_import_context ***/
1292   { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT },
1293   { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT },
1294   { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT },
1295   { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT },
1296   { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT },
1297
1298   /*** GLX_SGIX_fbconfig ***/
1299   { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX },
1300   { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX },
1301   { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX },
1302   { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX },
1303   { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX },
1304   { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX },
1305
1306   /*** GLX_SGIX_pbuffer ***/
1307   { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX },
1308   { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX },
1309   { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX },
1310   { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX },
1311   { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX },
1312
1313   /*** GLX_SGI_cushion ***/
1314   { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI },
1315
1316   /*** GLX_SGIX_video_resize ***/
1317   { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX },
1318   { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX },
1319   { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX },
1320   { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX },
1321   { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX },
1322
1323   /*** GLX_SGIX_dmbuffer **/
1324#if defined(_DM_BUFFER_H_)
1325   { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX },
1326#endif
1327
1328   /*** GLX_SGIX_swap_group ***/
1329   { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX },
1330
1331   /*** GLX_SGIX_swap_barrier ***/
1332   { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX },
1333   { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX },
1334
1335   /*** GLX_SUN_get_transparent_index ***/
1336   { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN },
1337
1338   /*** GLX_MESA_copy_sub_buffer ***/
1339   { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA },
1340
1341   /*** GLX_MESA_pixmap_colormap ***/
1342   { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA },
1343
1344   /*** GLX_MESA_release_buffers ***/
1345   { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA },
1346
1347   /*** GLX_MESA_set_3dfx_mode ***/
1348   { "glXSet3DfxModeMESA", (__GLXextFuncPtr) glXSet3DfxModeMESA },
1349
1350   /*** GLX_ARB_get_proc_address ***/
1351   { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB },
1352
1353   /*** GLX_NV_vertex_array_range ***/
1354   { "glXAllocateMemoryNV", (__GLXextFuncPtr) glXAllocateMemoryNV },
1355   { "glXFreeMemoryNV", (__GLXextFuncPtr) glXFreeMemoryNV },
1356
1357   /*** GLX_MESA_agp_offset ***/
1358   { "glXGetAGPOffsetMESA", (__GLXextFuncPtr) glXGetAGPOffsetMESA },
1359
1360   /*** GLX_MESA_allocate_memory ***/
1361   { "glXAllocateMemoryMESA", (__GLXextFuncPtr) glXAllocateMemoryMESA },
1362   { "glXFreeMemoryMESA", (__GLXextFuncPtr) glXFreeMemoryMESA },
1363   { "glXGetMemoryOffsetMESA", (__GLXextFuncPtr) glXGetMemoryOffsetMESA },
1364
1365   { NULL, NULL }   /* end of list */
1366};
1367
1368
1369
1370/*
1371 * Return address of named glX function, or NULL if not found.
1372 */
1373__GLXextFuncPtr
1374_glxapi_get_proc_address(const char *funcName)
1375{
1376   GLuint i;
1377   for (i = 0; GLX_functions[i].Name; i++) {
1378      if (strcmp(GLX_functions[i].Name, funcName) == 0)
1379         return GLX_functions[i].Address;
1380   }
1381   return NULL;
1382}
1383
1384
1385
1386/*
1387 * This function does not get dispatched through the dispatch table
1388 * since it's really a "meta" function.
1389 */
1390__GLXextFuncPtr
1391glXGetProcAddressARB(const GLubyte *procName)
1392{
1393   __GLXextFuncPtr f;
1394
1395   f = _glxapi_get_proc_address((const char *) procName);
1396   if (f) {
1397      return f;
1398   }
1399
1400   f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName);
1401   return f;
1402}
1403
1404
1405/* GLX 1.4 */
1406void (*glXGetProcAddress(const GLubyte *procName))()
1407{
1408   return glXGetProcAddressARB(procName);
1409}
1410