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