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